Added StrongPtr class to Loki along with tests for StrongPtr.
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@623 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
0201647cdc
commit
d5f4f0f77f
7 changed files with 3294 additions and 52 deletions
|
@ -1,11 +1,11 @@
|
|||
[Project]
|
||||
FileName=SmartPtr.dev
|
||||
Name=SmartPtr
|
||||
UnitCount=10
|
||||
UnitCount=12
|
||||
Type=1
|
||||
Ver=1
|
||||
ObjFiles=
|
||||
Includes=C:\Projects\loki\include
|
||||
Includes=C:\DevCpp\include;C:\Projects\loki\include
|
||||
Libs=
|
||||
PrivateResource=
|
||||
ResourceIncludes=
|
||||
|
@ -20,49 +20,49 @@ ObjectOutput=
|
|||
OverrideOutput=0
|
||||
OverrideOutputName=SmartPtr.exe
|
||||
HostApplication=
|
||||
Folders=Loki_Headers,Loki_Sources,Test
|
||||
Folders=Headers,Sources,Tests
|
||||
CommandLine=
|
||||
UseCustomMakefile=0
|
||||
CustomMakefile=
|
||||
IncludeVersionInfo=0
|
||||
SupportXPThemes=0
|
||||
CompilerSet=0
|
||||
CompilerSettings=1000001001001001000000
|
||||
CompilerSettings=0000001001001001000000
|
||||
|
||||
[Unit1]
|
||||
FileName=..\..\src\Singleton.cpp
|
||||
FileName=main.cpp
|
||||
CompileCpp=1
|
||||
Folder=Loki_Sources
|
||||
Folder=Tests
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit2]
|
||||
FileName=..\..\src\SmallObj.cpp
|
||||
FileName=..\..\src\Singleton.cpp
|
||||
CompileCpp=1
|
||||
Folder=Loki_Sources
|
||||
Folder=Sources
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=2
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit3]
|
||||
FileName=..\..\src\SmartPtr.cpp
|
||||
FileName=..\..\src\SmallObj.cpp
|
||||
CompileCpp=1
|
||||
Folder=Loki_Sources
|
||||
Folder=Sources
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=3
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit4]
|
||||
FileName=..\..\include\loki\Threads.h
|
||||
CompileCpp=1
|
||||
Folder=Loki_Headers
|
||||
Folder=Headers
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
|
@ -70,9 +70,9 @@ OverrideBuildCmd=0
|
|||
BuildCmd=
|
||||
|
||||
[Unit5]
|
||||
FileName=..\..\include\loki\ConstPolicy.h
|
||||
FileName=..\..\include\loki\Singleton.h
|
||||
CompileCpp=1
|
||||
Folder=Loki_Headers
|
||||
Folder=Headers
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
|
@ -80,9 +80,9 @@ OverrideBuildCmd=0
|
|||
BuildCmd=
|
||||
|
||||
[Unit6]
|
||||
FileName=..\..\include\loki\Singleton.h
|
||||
FileName=..\..\include\loki\SmallObj.h
|
||||
CompileCpp=1
|
||||
Folder=Loki_Headers
|
||||
Folder=Headers
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
|
@ -90,39 +90,9 @@ OverrideBuildCmd=0
|
|||
BuildCmd=
|
||||
|
||||
[Unit7]
|
||||
FileName=..\..\include\loki\SmallObj.h
|
||||
CompileCpp=1
|
||||
Folder=Loki_Headers
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit8]
|
||||
FileName=..\..\include\loki\SmartPtr.h
|
||||
CompileCpp=1
|
||||
Folder=Loki_Headers
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit9]
|
||||
FileName=main.cpp
|
||||
CompileCpp=1
|
||||
Folder=Test
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit10]
|
||||
FileName=base.h
|
||||
CompileCpp=1
|
||||
Folder=Test
|
||||
Folder=Headers
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
|
@ -147,3 +117,53 @@ ProductName=
|
|||
ProductVersion=
|
||||
AutoIncBuildNr=0
|
||||
|
||||
[Unit8]
|
||||
FileName=strong.cpp
|
||||
CompileCpp=1
|
||||
Folder=Tests
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit9]
|
||||
FileName=..\..\src\StrongPtr.cpp
|
||||
CompileCpp=1
|
||||
Folder=Sources
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit10]
|
||||
FileName=..\..\include\loki\StrongPtr.h
|
||||
CompileCpp=1
|
||||
Folder=Headers
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit11]
|
||||
FileName=..\..\src\SmartPtr.cpp
|
||||
CompileCpp=1
|
||||
Folder=Sources
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit12]
|
||||
FileName=base.h
|
||||
CompileCpp=1
|
||||
Folder=Tests
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8,00"
|
||||
Version="8.00"
|
||||
Name="SmartPtr"
|
||||
ProjectGUID="{D7AB4FEF-E7AF-443D-93A5-37F323F2042D}"
|
||||
RootNamespace="SmartPtr"
|
||||
|
@ -150,6 +150,10 @@
|
|||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\base.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\main.cpp"
|
||||
>
|
||||
|
@ -178,6 +182,18 @@
|
|||
RelativePath="..\..\include\loki\SmartPtr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\strong.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\StrongPtr.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\loki\StrongPtr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\loki\Threads.h"
|
||||
>
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
// $Header$
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
@ -38,6 +40,8 @@ public:
|
|||
return new BaseClass();
|
||||
}
|
||||
|
||||
void DoThat( void ) const {}
|
||||
|
||||
static inline bool AllDestroyed( void )
|
||||
{
|
||||
return ( s_constructions == s_destructions );
|
||||
|
@ -82,7 +86,7 @@ public:
|
|||
// This function is used only for the DeepCopy policy.
|
||||
virtual BaseClass * Clone( void ) const
|
||||
{
|
||||
return new BaseClass;
|
||||
return new PublicSubClass;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -94,13 +98,98 @@ public:
|
|||
// This function is used only for the DeepCopy policy.
|
||||
virtual BaseClass * Clone( void ) const
|
||||
{
|
||||
return new BaseClass;
|
||||
return new PrivateSubClass;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** @class MimicCOM Acts like a COM object by having an intrusive ref count.
|
||||
*/
|
||||
class MimicCOM
|
||||
{
|
||||
public:
|
||||
MimicCOM( void )
|
||||
: m_count( 0 )
|
||||
, m_AddRefCount( 0 )
|
||||
, m_ReleaseCount( 0 )
|
||||
{
|
||||
s_constructions++;
|
||||
}
|
||||
|
||||
virtual ~MimicCOM( void )
|
||||
{
|
||||
s_destructions++;
|
||||
}
|
||||
|
||||
void AddRef( void )
|
||||
{
|
||||
m_count++;
|
||||
m_AddRefCount++;
|
||||
}
|
||||
|
||||
void Release( void )
|
||||
{
|
||||
m_ReleaseCount++;
|
||||
assert( 0 < m_count );
|
||||
m_count--;
|
||||
if ( 0 == m_count )
|
||||
{
|
||||
/** @note I consider "delete this;" to be very unsafe! I'm only
|
||||
using it here for the purpose of testing.
|
||||
*/
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void DoThat( void ) {}
|
||||
|
||||
static inline bool AllDestroyed( void )
|
||||
{
|
||||
return ( s_constructions == s_destructions );
|
||||
}
|
||||
|
||||
static inline bool ExtraConstructions( void )
|
||||
{
|
||||
return ( s_constructions > s_destructions );
|
||||
}
|
||||
|
||||
static inline bool ExtraDestructions( void )
|
||||
{
|
||||
return ( s_constructions < s_destructions );
|
||||
}
|
||||
|
||||
static inline unsigned int GetCtorCount( void )
|
||||
{
|
||||
return s_constructions;
|
||||
}
|
||||
|
||||
static inline unsigned int GetDtorCount( void )
|
||||
{
|
||||
return s_destructions;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Not implemented.
|
||||
MimicCOM( const MimicCOM & );
|
||||
/// Not implemented.
|
||||
MimicCOM & operator = ( const MimicCOM & );
|
||||
|
||||
static unsigned int s_constructions;
|
||||
static unsigned int s_destructions;
|
||||
|
||||
unsigned int m_count;
|
||||
unsigned int m_AddRefCount;
|
||||
unsigned int m_ReleaseCount;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// $Log$
|
||||
// Revision 1.2 2006/04/05 22:53:12 rich_sposato
|
||||
// Added StrongPtr class to Loki along with tests for StrongPtr.
|
||||
//
|
||||
// Revision 1.1 2006/03/20 21:14:16 rich_sposato
|
||||
// Adding base.h to CVS.
|
||||
//
|
||||
|
|
|
@ -27,10 +27,31 @@ using namespace Loki;
|
|||
|
||||
extern void DoStrongRefCountTests( void );
|
||||
extern void DoStrongRefLinkTests( void );
|
||||
extern void DoStrongReleaseTests( void );
|
||||
extern void DoWeakCycleTests( void );
|
||||
extern void DoStrongConstTests( void );
|
||||
extern void DoStrongForwardReferenceTest( void );
|
||||
|
||||
unsigned int BaseClass::s_constructions = 0;
|
||||
unsigned int BaseClass::s_destructions = 0;
|
||||
|
||||
unsigned int MimicCOM::s_constructions = 0;
|
||||
unsigned int MimicCOM::s_destructions = 0;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// Used to check if SmartPtr can be used with a forward-reference.
|
||||
class Thingy;
|
||||
|
||||
typedef Loki::SmartPtr< Thingy, RefCounted, DisallowConversion,
|
||||
AssertCheck, DefaultSPStorage, PropagateConst >
|
||||
Thingy_DefaultStorage_ptr;
|
||||
|
||||
typedef Loki::SmartPtr< Thingy, RefCounted, DisallowConversion,
|
||||
AssertCheck, HeapStorage, PropagateConst >
|
||||
Thingy_HeapStorage_ptr;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
@ -53,6 +74,8 @@ typedef Loki::SmartPtr< BaseClass, RefCounted, DisallowConversion,
|
|||
NonConstBase_RefCount_NoConvert_Assert_Propagate_ptr;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// @note These 5 are used for testing ownership policies.
|
||||
typedef Loki::SmartPtr< BaseClass, COMRefCounted, DisallowConversion,
|
||||
AssertCheck, DefaultSPStorage, DontPropagateConst >
|
||||
|
@ -74,6 +97,9 @@ typedef Loki::SmartPtr< BaseClass, NoCopy, DisallowConversion,
|
|||
AssertCheck, DefaultSPStorage, DontPropagateConst >
|
||||
NonConstBase_NoCopy_NoConvert_Assert_DontPropagate_ptr;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// @note These 2 are used for testing inheritance.
|
||||
typedef Loki::SmartPtr< PublicSubClass, RefCounted, DisallowConversion,
|
||||
AssertCheck, DefaultSPStorage, DontPropagateConst >
|
||||
|
@ -84,6 +110,14 @@ typedef Loki::SmartPtr< PrivateSubClass, RefCounted, DisallowConversion,
|
|||
PrivateSub_RefCount_NoConvert_Assert_DontPropagate_ptr;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// @note Used for testing how well SmartPtr works with COM objects.
|
||||
typedef Loki::SmartPtr< MimicCOM, COMRefCounted, DisallowConversion,
|
||||
AssertCheck, DefaultSPStorage, DontPropagateConst >
|
||||
MimicCOM_ptr;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoConstConversionTests( void )
|
||||
|
@ -303,6 +337,8 @@ void DoRefLinkSwapTests( void )
|
|||
BaseClass * pBaseClass = new BaseClass;
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p1( pBaseClass );
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p2( new BaseClass );
|
||||
p1->DoThat();
|
||||
p2->DoThat();
|
||||
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p3( p1 );
|
||||
NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p4( p2 );
|
||||
|
@ -785,6 +821,7 @@ void DoRefLinkTests( void )
|
|||
assert( w3 );
|
||||
assert( w4 );
|
||||
assert( dtorCount + 1 == BaseClass::GetDtorCount() );
|
||||
w3->DoThat();
|
||||
}
|
||||
assert( ctorCount + 2 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 2 == BaseClass::GetDtorCount() );
|
||||
|
@ -902,16 +939,80 @@ void DoRefLinkNullPointerTests( void )
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoComRefTest( void )
|
||||
{
|
||||
|
||||
const unsigned int ctorCount = MimicCOM::GetCtorCount();
|
||||
const unsigned int dtorCount = MimicCOM::GetDtorCount();
|
||||
assert( MimicCOM::AllDestroyed() );
|
||||
{
|
||||
MimicCOM_ptr p1;
|
||||
}
|
||||
assert( MimicCOM::AllDestroyed() );
|
||||
assert( ctorCount == MimicCOM::GetCtorCount() );
|
||||
assert( dtorCount == MimicCOM::GetDtorCount() );
|
||||
|
||||
{
|
||||
MimicCOM_ptr p1( new MimicCOM );
|
||||
}
|
||||
assert( ctorCount+1 == MimicCOM::GetCtorCount() );
|
||||
assert( dtorCount+1 == MimicCOM::GetDtorCount() );
|
||||
|
||||
{
|
||||
MimicCOM_ptr p2( new MimicCOM );
|
||||
MimicCOM_ptr p3( p2 );
|
||||
MimicCOM_ptr p4;
|
||||
p4 = p2;
|
||||
}
|
||||
assert( ctorCount+2 == MimicCOM::GetCtorCount() );
|
||||
assert( dtorCount+2 == MimicCOM::GetDtorCount() );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoForwardReferenceTest( void )
|
||||
{
|
||||
/** @note These lines should cause the compiler to make a warning message
|
||||
about attempting to delete an undefined type. But it should not produce
|
||||
any error messages.
|
||||
*/
|
||||
Thingy_DefaultStorage_ptr p1;
|
||||
Thingy_DefaultStorage_ptr p2( p1 );
|
||||
Thingy_DefaultStorage_ptr p3;
|
||||
p3 = p2;
|
||||
|
||||
/** @note These lines should cause the compiler to make an error message
|
||||
about attempting to call the destructor for an undefined type.
|
||||
*/
|
||||
//Thingy_HeapStorage_ptr p4;
|
||||
//Thingy_HeapStorage_ptr p5( p4 );
|
||||
//Thingy_HeapStorage_ptr p6;
|
||||
//p6 = p5;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int main( unsigned int , const char * [] )
|
||||
{
|
||||
|
||||
DoRefLinkTests();
|
||||
DoStrongRefCountTests();
|
||||
DoStrongRefLinkTests();
|
||||
DoStrongReleaseTests();
|
||||
DoWeakCycleTests();
|
||||
|
||||
DoForwardReferenceTest();
|
||||
DoStrongForwardReferenceTest();
|
||||
|
||||
DoRefCountNullPointerTests();
|
||||
DoRefLinkNullPointerTests();
|
||||
|
||||
DoRefCountSwapTests();
|
||||
DoRefLinkSwapTests();
|
||||
|
||||
DoComRefTest();
|
||||
|
||||
DoStrongConstTests();
|
||||
DoConstConversionTests();
|
||||
DoOwnershipConversionTests();
|
||||
DoInheritanceConversionTests();
|
||||
|
@ -930,6 +1031,9 @@ int main( unsigned int , const char * [] )
|
|||
// ----------------------------------------------------------------------------
|
||||
|
||||
// $Log$
|
||||
// Revision 1.5 2006/04/05 22:53:12 rich_sposato
|
||||
// Added StrongPtr class to Loki along with tests for StrongPtr.
|
||||
//
|
||||
// Revision 1.4 2006/03/21 20:50:22 syntheticpp
|
||||
// fix include error
|
||||
//
|
||||
|
|
935
test/SmartPtr/strong.cpp
Normal file
935
test/SmartPtr/strong.cpp
Normal file
|
@ -0,0 +1,935 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Test program for The Loki Library
|
||||
// Copyright (c) 2006 Richard Sposato
|
||||
// Permission to use, copy, modify, distribute and sell this software for any
|
||||
// purpose is hereby granted without fee, provided that the above copyright
|
||||
// notice appear in all copies and that both that copyright notice and this
|
||||
// permission notice appear in supporting documentation.
|
||||
// The authors make no representations about the
|
||||
// suitability of this software for any purpose. It is provided "as is"
|
||||
// without express or implied warranty.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// $Header$
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <loki/StrongPtr.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
#include "base.h"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using namespace std;
|
||||
using namespace Loki;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// Used to check if SmartPtr can be used with a forward-reference.
|
||||
class Thingy;
|
||||
|
||||
typedef Loki::StrongPtr< Thingy, true, TwoRefCounts, DisallowConversion,
|
||||
AssertCheck, CantResetWithStrong, DeleteSingle, DontPropagateConst >
|
||||
Thingy_DeleteSingle_ptr;
|
||||
|
||||
typedef Loki::StrongPtr< Thingy, true, TwoRefCounts, DisallowConversion,
|
||||
AssertCheck, CantResetWithStrong, DeleteUsingFree, DontPropagateConst >
|
||||
Thingy_DeleteUsingFree_ptr;
|
||||
|
||||
typedef Loki::StrongPtr< Thingy, true, TwoRefCounts, DisallowConversion,
|
||||
AssertCheck, CantResetWithStrong, DeleteNothing, DontPropagateConst >
|
||||
Thingy_DeleteNothing_ptr;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class Earth;
|
||||
class Moon;
|
||||
|
||||
typedef Loki::StrongPtr< Earth, false, TwoRefCounts, DisallowConversion,
|
||||
AssertCheck, CantResetWithStrong, DeleteSingle, DontPropagateConst >
|
||||
Earth_WeakPtr;
|
||||
|
||||
typedef Loki::StrongPtr< Earth, true, TwoRefCounts, DisallowConversion,
|
||||
AssertCheck, AllowReset, DeleteSingle, DontPropagateConst >
|
||||
Earth_StrongPtr;
|
||||
|
||||
typedef Loki::StrongPtr< Moon, false, TwoRefCounts, DisallowConversion,
|
||||
AssertCheck, CantResetWithStrong, DeleteSingle, DontPropagateConst >
|
||||
Moon_WeakPtr;
|
||||
|
||||
typedef Loki::StrongPtr< Moon, true, TwoRefCounts, DisallowConversion,
|
||||
AssertCheck, AllowReset, DeleteSingle, DontPropagateConst >
|
||||
Moon_StrongPtr;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class Earth
|
||||
{
|
||||
public:
|
||||
|
||||
Earth( void ) : m_moon()
|
||||
{
|
||||
s_constructions++;
|
||||
}
|
||||
|
||||
~Earth( void )
|
||||
{
|
||||
s_destructions++;
|
||||
}
|
||||
|
||||
void SetMoon( const Moon_StrongPtr & p );
|
||||
|
||||
void SetMoon( const Moon_WeakPtr & p );
|
||||
|
||||
static inline bool AllDestroyed( void )
|
||||
{
|
||||
return ( s_constructions == s_destructions );
|
||||
}
|
||||
|
||||
static inline bool ExtraConstructions( void )
|
||||
{
|
||||
return ( s_constructions > s_destructions );
|
||||
}
|
||||
|
||||
static inline bool ExtraDestructions( void )
|
||||
{
|
||||
return ( s_constructions < s_destructions );
|
||||
}
|
||||
|
||||
static inline unsigned int GetCtorCount( void )
|
||||
{
|
||||
return s_constructions;
|
||||
}
|
||||
|
||||
static inline unsigned int GetDtorCount( void )
|
||||
{
|
||||
return s_destructions;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Not implemented.
|
||||
Earth( const Earth & );
|
||||
/// Not implemented.
|
||||
Earth & operator = ( const Earth & );
|
||||
|
||||
static unsigned int s_constructions;
|
||||
static unsigned int s_destructions;
|
||||
|
||||
Moon_WeakPtr m_moon;
|
||||
};
|
||||
|
||||
unsigned int Earth::s_constructions = 0;
|
||||
unsigned int Earth::s_destructions = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class Moon
|
||||
{
|
||||
public:
|
||||
|
||||
Moon( void ) : m_earth()
|
||||
{
|
||||
s_constructions++;
|
||||
}
|
||||
|
||||
~Moon( void )
|
||||
{
|
||||
s_destructions++;
|
||||
}
|
||||
|
||||
void SetEarth( const Earth_WeakPtr & p );
|
||||
|
||||
void SetEarth( const Earth_StrongPtr & p );
|
||||
|
||||
static inline bool AllDestroyed( void )
|
||||
{
|
||||
return ( s_constructions == s_destructions );
|
||||
}
|
||||
|
||||
static inline bool ExtraConstructions( void )
|
||||
{
|
||||
return ( s_constructions > s_destructions );
|
||||
}
|
||||
|
||||
static inline bool ExtraDestructions( void )
|
||||
{
|
||||
return ( s_constructions < s_destructions );
|
||||
}
|
||||
|
||||
static inline unsigned int GetCtorCount( void )
|
||||
{
|
||||
return s_constructions;
|
||||
}
|
||||
|
||||
static inline unsigned int GetDtorCount( void )
|
||||
{
|
||||
return s_destructions;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Not implemented.
|
||||
Moon( const Moon & );
|
||||
/// Not implemented.
|
||||
Moon & operator = ( const Moon & );
|
||||
|
||||
static unsigned int s_constructions;
|
||||
static unsigned int s_destructions;
|
||||
Earth_WeakPtr m_earth;
|
||||
};
|
||||
|
||||
unsigned int Moon::s_constructions = 0;
|
||||
unsigned int Moon::s_destructions = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Moon::SetEarth( const Earth_WeakPtr & p )
|
||||
{
|
||||
m_earth = p;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Moon::SetEarth( const Earth_StrongPtr & p )
|
||||
{
|
||||
m_earth = p;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Earth::SetMoon( const Moon_WeakPtr & p )
|
||||
{
|
||||
m_moon = p;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void Earth::SetMoon( const Moon_StrongPtr & p )
|
||||
{
|
||||
m_moon = p;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
typedef Loki::StrongPtr< BaseClass, false, TwoRefCounts, DisallowConversion,
|
||||
AssertCheck, CantResetWithStrong, DeleteSingle, DontPropagateConst >
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr;
|
||||
|
||||
typedef Loki::StrongPtr< BaseClass, true, TwoRefCounts, DisallowConversion,
|
||||
NoCheck, CantResetWithStrong, DeleteSingle, DontPropagateConst >
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr;
|
||||
|
||||
typedef Loki::StrongPtr< BaseClass, false, TwoRefLinks, DisallowConversion,
|
||||
AssertCheck, CantResetWithStrong, DeleteSingle, DontPropagateConst >
|
||||
NonConstBase_WeakLink_NoConvert_Assert_NoPropagate_ptr;
|
||||
|
||||
typedef Loki::StrongPtr< BaseClass, true, TwoRefLinks, DisallowConversion,
|
||||
NoCheck, CantResetWithStrong, DeleteSingle, DontPropagateConst >
|
||||
NonConstBase_StrongLink_NoConvert_NoCheck_NoPropagate_ptr;
|
||||
|
||||
typedef Loki::StrongPtr< BaseClass, false, TwoRefCounts, DisallowConversion,
|
||||
AssertCheck, AllowReset, DeleteSingle, DontPropagateConst >
|
||||
NonConstBase_WeakCount_NoConvert_Assert_Reset_NoPropagate_ptr;
|
||||
|
||||
typedef Loki::StrongPtr< BaseClass, true, TwoRefCounts, DisallowConversion,
|
||||
NoCheck, AllowReset, DeleteSingle, DontPropagateConst >
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_Reset_NoPropagate_ptr;
|
||||
|
||||
/// @note Used for const propagation tests.
|
||||
typedef Loki::StrongPtr< const BaseClass, true, TwoRefCounts, DisallowConversion,
|
||||
NoCheck, CantResetWithStrong, DeleteSingle, PropagateConst >
|
||||
ConstBase_StrongCount_NoConvert_NoCheck_Propagate_ptr;
|
||||
|
||||
typedef Loki::StrongPtr< const BaseClass, false, TwoRefCounts, DisallowConversion,
|
||||
AssertCheck, CantResetWithStrong, DeleteSingle, PropagateConst >
|
||||
ConstBase_WeakCount_NoConvert_Assert_Propagate_ptr;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoStrongRefCountTests( void )
|
||||
{
|
||||
|
||||
BaseClass * pNull = NULL;
|
||||
const unsigned int ctorCount = BaseClass::GetCtorCount();
|
||||
const unsigned int dtorCount = BaseClass::GetDtorCount();
|
||||
assert( BaseClass::GetCtorCount() == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w0;
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s0;
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w1( w0 );
|
||||
|
||||
// Copy from weak to strong is available.
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s1( w0 );
|
||||
// Assignment from weak to strong is available.
|
||||
s1 = w1;
|
||||
|
||||
// Converting from strong to weak is available.
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w2( s0 );
|
||||
// Assignment from strong to weak is available.
|
||||
w1 = s1;
|
||||
|
||||
assert( !s0 );
|
||||
assert( !s1 );
|
||||
assert( !w0 );
|
||||
assert( !w1 );
|
||||
assert( s1 == pNull );
|
||||
assert( s0 == pNull );
|
||||
assert( w1 == pNull );
|
||||
assert( w1 == pNull );
|
||||
assert( pNull == s0 );
|
||||
assert( pNull == s1 );
|
||||
assert( pNull == w0 );
|
||||
assert( pNull == w1 );
|
||||
assert( s0 == s0 );
|
||||
assert( s1 == s1 );
|
||||
assert( w0 == w0 );
|
||||
assert( w1 == w1 );
|
||||
assert( s1 == s0 );
|
||||
assert( s0 == s1 );
|
||||
assert( w0 == s0 );
|
||||
assert( s0 == w0 );
|
||||
assert( w0 == w1 );
|
||||
assert( w1 == w0 );
|
||||
assert( w0 == w1 );
|
||||
assert( w1 == s1 );
|
||||
assert( s1 == w1 );
|
||||
assert( s1 <= s0 );
|
||||
assert( s1 >= s0 );
|
||||
assert( s0 <= s1 );
|
||||
assert( s0 >= s1 );
|
||||
assert( w0 <= s0 );
|
||||
assert( w0 >= s0 );
|
||||
assert( s0 <= w0 );
|
||||
assert( s0 >= w0 );
|
||||
assert( w1 <= w0 );
|
||||
assert( w1 >= w0 );
|
||||
assert( w0 <= w1 );
|
||||
assert( w0 >= w1 );
|
||||
assert( !( s1 < s0 ) );
|
||||
assert( !( s1 > s0 ) );
|
||||
assert( !( s0 < s1 ) );
|
||||
assert( !( s0 > s1 ) );
|
||||
assert( !( w0 < s0 ) );
|
||||
assert( !( w0 > s0 ) );
|
||||
assert( !( s0 < w0 ) );
|
||||
assert( !( s0 > w0 ) );
|
||||
assert( !( w1 < w0 ) );
|
||||
assert( !( w1 > w0 ) );
|
||||
assert( !( w0 < w1 ) );
|
||||
assert( !( w0 > w1 ) );
|
||||
assert( !( w0 < pNull ) );
|
||||
assert( !( w0 > pNull ) );
|
||||
assert( !( pNull < w0 ) );
|
||||
assert( !( pNull > w0 ) );
|
||||
}
|
||||
assert( ctorCount == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w1( new BaseClass );
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w2( new BaseClass );
|
||||
assert( w1 != w2 );
|
||||
assert( w1 );
|
||||
assert( w2 );
|
||||
w1 = w2;
|
||||
assert( w1 == w2 );
|
||||
assert( w1 );
|
||||
assert( w2 );
|
||||
assert( dtorCount + 1 == BaseClass::GetDtorCount() );
|
||||
}
|
||||
assert( ctorCount + 2 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 2 == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s1( new BaseClass );
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s2( new BaseClass );
|
||||
assert( s1 != s2 );
|
||||
assert( s1 );
|
||||
assert( s2 );
|
||||
s1 = s2;
|
||||
assert( s1 == s2 );
|
||||
assert( s1 );
|
||||
assert( s2 );
|
||||
assert( dtorCount + 3 == BaseClass::GetDtorCount() );
|
||||
}
|
||||
assert( ctorCount + 4 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 4 == BaseClass::GetDtorCount() );
|
||||
assert( BaseClass::GetCtorCount() == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w1( new BaseClass );
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w2( new BaseClass );
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s1( w1 );
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s2( w2 );
|
||||
|
||||
// prove basic stuff.
|
||||
assert( w1 != w2 );
|
||||
assert( s1 != s2 );
|
||||
assert( s1 == w1 );
|
||||
assert( s2 == w2 );
|
||||
assert( s1 );
|
||||
assert( s2 );
|
||||
assert( w1 );
|
||||
assert( w2 );
|
||||
|
||||
// prove a weak pointer can be re-assigned to another without affecting
|
||||
// any strong co-pointers. and that no objects were released.
|
||||
w1 = w2; // w1 == w2 == s2 s1
|
||||
assert( w1 == w2 );
|
||||
assert( s1 != s2 );
|
||||
assert( s1 != w1 );
|
||||
assert( s1 != w2 );
|
||||
assert( s2 == w1 );
|
||||
assert( w1 );
|
||||
assert( w2 );
|
||||
assert( s1 );
|
||||
assert( s2 );
|
||||
assert( dtorCount + 4 == BaseClass::GetDtorCount() );
|
||||
|
||||
// Prove they all point to same thing.
|
||||
s1 = s2; // w1 == w2 == s2 == s1
|
||||
// and prove that one of them released the object.
|
||||
assert( dtorCount + 5 == BaseClass::GetDtorCount() );
|
||||
assert( w1 == w2 );
|
||||
assert( s1 == s2 );
|
||||
assert( s1 == w1 );
|
||||
assert( s1 == w2 );
|
||||
assert( s2 == w1 );
|
||||
assert( w1 );
|
||||
assert( w2 );
|
||||
assert( s1 );
|
||||
assert( s2 );
|
||||
}
|
||||
assert( ctorCount + 6 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 6 == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w1( new BaseClass );
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w2( new BaseClass );
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s1( w1 );
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s2( w2 );
|
||||
|
||||
// prove basic stuff. w1 == s1 w2 == s2
|
||||
assert( w1 != w2 );
|
||||
assert( s1 != s2 );
|
||||
assert( s1 == w1 );
|
||||
assert( s2 == w2 );
|
||||
assert( s1 );
|
||||
assert( s2 );
|
||||
assert( w1 );
|
||||
assert( w2 );
|
||||
|
||||
// prove a strong pointer can be re-assigned to another weak pointer,
|
||||
// and that any weak co-pointers released the object.
|
||||
s1 = w2; // s1 == w2 == s2 w1
|
||||
assert( w1 != w2 );
|
||||
assert( s1 == s2 );
|
||||
assert( s1 != w1 );
|
||||
assert( s1 == w2 );
|
||||
assert( s2 != w1 );
|
||||
assert( !w1 );
|
||||
assert( w2 );
|
||||
assert( s1 );
|
||||
assert( s2 );
|
||||
assert( dtorCount + 7 == BaseClass::GetDtorCount() );
|
||||
|
||||
// Prove that when strong pointer is re-assigned, object
|
||||
// is not destroyed if another strong co-pointer exists.
|
||||
s1 = w1; // w1 == s1 w2 == s2
|
||||
// and prove that none of them released an object.
|
||||
assert( dtorCount + 7 == BaseClass::GetDtorCount() );
|
||||
assert( w1 != w2 );
|
||||
assert( s1 != s2 );
|
||||
assert( s1 == w1 );
|
||||
assert( s2 == w2 );
|
||||
assert( !s1 );
|
||||
assert( s2 );
|
||||
assert( !w1 );
|
||||
assert( w2 );
|
||||
}
|
||||
assert( ctorCount + 8 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 8 == BaseClass::GetDtorCount() );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoStrongConstTests( void )
|
||||
{
|
||||
|
||||
const unsigned int ctorCount = BaseClass::GetCtorCount();
|
||||
const unsigned int dtorCount = BaseClass::GetDtorCount();
|
||||
assert( BaseClass::GetCtorCount() == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w1( new BaseClass );
|
||||
const NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w2( w1 );
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s1( w1 );
|
||||
const NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s2( w2 );
|
||||
|
||||
const BaseClass & cbw1 = *w1;
|
||||
cbw1.DoThat();
|
||||
const BaseClass & cbw2 = *w2;
|
||||
cbw2.DoThat();
|
||||
const BaseClass & cbs1 = *s1;
|
||||
cbs1.DoThat();
|
||||
const BaseClass & cbs2 = *s2;
|
||||
cbs2.DoThat();
|
||||
|
||||
BaseClass & bw1 = *w1;
|
||||
bw1.DoThat();
|
||||
BaseClass & bw2 = *w2;
|
||||
bw2.DoThat();
|
||||
BaseClass & bs1 = *s1;
|
||||
bs1.DoThat();
|
||||
BaseClass & bs2 = *s2;
|
||||
bs2.DoThat();
|
||||
}
|
||||
assert( ctorCount + 1 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 1 == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
ConstBase_WeakCount_NoConvert_Assert_Propagate_ptr w1( new BaseClass );
|
||||
const ConstBase_WeakCount_NoConvert_Assert_Propagate_ptr w2( w1 );
|
||||
ConstBase_StrongCount_NoConvert_NoCheck_Propagate_ptr s1( w1 );
|
||||
const ConstBase_StrongCount_NoConvert_NoCheck_Propagate_ptr s2( w2 );
|
||||
|
||||
const BaseClass & cbw1 = *w1;
|
||||
cbw1.DoThat();
|
||||
const BaseClass & cbw2 = *w2;
|
||||
cbw2.DoThat();
|
||||
const BaseClass & cbs1 = *s1;
|
||||
cbs1.DoThat();
|
||||
const BaseClass & cbs2 = *s2;
|
||||
cbs2.DoThat();
|
||||
|
||||
/** @note These are illegal because constness is propagated by the
|
||||
StrongPtr's policy. Your compiler should produce error messages if
|
||||
you attempt to compile these lines.
|
||||
*/
|
||||
//BaseClass & bw1 = *w1;
|
||||
//bw1.DoThat();
|
||||
//BaseClass & bw2 = *w2;
|
||||
//bw2.DoThat();
|
||||
//BaseClass & bs1 = *s1;
|
||||
//bs1.DoThat();
|
||||
//BaseClass & bs2 = *s2;
|
||||
//bs2.DoThat();
|
||||
}
|
||||
assert( ctorCount + 2 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 2 == BaseClass::GetDtorCount() );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoStrongReleaseTests( void )
|
||||
{
|
||||
|
||||
BaseClass * pNull = NULL;
|
||||
const unsigned int ctorCount = BaseClass::GetCtorCount();
|
||||
const unsigned int dtorCount = BaseClass::GetDtorCount();
|
||||
assert( BaseClass::GetCtorCount() == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
// These are tests of pointers that don't allow reset or release if
|
||||
// there is at least 1 strong pointer. Ironically, this means that
|
||||
// if only 1 strong pointer holds onto an object, and you call Release
|
||||
// using that strong pointer, it can't release itself.
|
||||
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w1( new BaseClass );
|
||||
NonConstBase_WeakCount_NoConvert_Assert_NoPropagate_ptr w2( new BaseClass );
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s1( w1 );
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_NoPropagate_ptr s2( w2 );
|
||||
|
||||
// Prove that neither weak nor strong pointers can be
|
||||
// released if any co-pointer is strong.
|
||||
bool released = ReleaseAll( w2, pNull );
|
||||
assert( !released );
|
||||
|
||||
released = ReleaseAll( w1, pNull );
|
||||
assert( !released );
|
||||
|
||||
released = ReleaseAll( s1, pNull );
|
||||
assert( !released );
|
||||
|
||||
released = ReleaseAll( s2, pNull );
|
||||
assert( !released );
|
||||
|
||||
// Prove that weak and strong pointers can be reset only
|
||||
// if stored pointer matches parameter pointer - or there
|
||||
// are no strong co-pointers.
|
||||
bool reset = ResetAll( w2, pNull );
|
||||
assert( !reset );
|
||||
|
||||
reset = ResetAll( w1, pNull );
|
||||
assert( !reset );
|
||||
|
||||
reset = ResetAll( s1, pNull );
|
||||
assert( !reset );
|
||||
|
||||
reset = ResetAll( s2, pNull );
|
||||
assert( !reset );
|
||||
|
||||
s2 = pNull;
|
||||
assert( dtorCount + 1 == BaseClass::GetDtorCount() );
|
||||
reset = ResetAll( w2, pNull );
|
||||
assert( reset );
|
||||
|
||||
reset = ResetAll( w1, pNull );
|
||||
assert( !reset );
|
||||
|
||||
reset = ResetAll( s1, pNull );
|
||||
assert( !reset );
|
||||
|
||||
reset = ResetAll( s2, pNull );
|
||||
assert( reset );
|
||||
}
|
||||
assert( ctorCount + 2 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 2 == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
// These are tests of pointers that do allow reset and release even
|
||||
// if a strong pointer exists.
|
||||
|
||||
NonConstBase_WeakCount_NoConvert_Assert_Reset_NoPropagate_ptr w1( new BaseClass );
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_Reset_NoPropagate_ptr w2( new BaseClass );
|
||||
NonConstBase_WeakCount_NoConvert_Assert_Reset_NoPropagate_ptr s1( w1 );
|
||||
NonConstBase_StrongCount_NoConvert_NoCheck_Reset_NoPropagate_ptr s2( w2 );
|
||||
|
||||
BaseClass * thing = NULL;
|
||||
bool released = ReleaseAll( w2, thing );
|
||||
assert( released );
|
||||
assert( NULL != thing );
|
||||
delete thing;
|
||||
assert( dtorCount + 3 == BaseClass::GetDtorCount() );
|
||||
|
||||
released = ReleaseAll( s1, thing );
|
||||
assert( released );
|
||||
assert( NULL != thing );
|
||||
delete thing;
|
||||
assert( dtorCount + 4 == BaseClass::GetDtorCount() );
|
||||
|
||||
released = ReleaseAll( w1, thing );
|
||||
assert( released );
|
||||
assert( NULL == thing );
|
||||
|
||||
released = ReleaseAll( s2, thing );
|
||||
assert( released );
|
||||
assert( NULL == thing );
|
||||
|
||||
// Prove that weak and strong pointers can be reset
|
||||
// only if stored pointer matches parameter pointer
|
||||
// - even if there are strong co-pointers.
|
||||
bool reset = ResetAll( w2, pNull );
|
||||
assert( reset );
|
||||
|
||||
reset = ResetAll( w1, pNull );
|
||||
assert( reset );
|
||||
|
||||
reset = ResetAll( s1, pNull );
|
||||
assert( reset );
|
||||
|
||||
reset = ResetAll( s2, pNull );
|
||||
assert( reset );
|
||||
assert( ctorCount + 4 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 4 == BaseClass::GetDtorCount() );
|
||||
|
||||
s2 = new BaseClass;
|
||||
s1 = new BaseClass;
|
||||
reset = ResetAll( w2, pNull );
|
||||
assert( reset );
|
||||
|
||||
reset = ResetAll( w1, pNull );
|
||||
assert( reset );
|
||||
}
|
||||
assert( ctorCount + 6 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 6 == BaseClass::GetDtorCount() );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoStrongRefLinkTests( void )
|
||||
{
|
||||
|
||||
BaseClass * pNull = NULL;
|
||||
const unsigned int ctorCount = BaseClass::GetCtorCount();
|
||||
const unsigned int dtorCount = BaseClass::GetDtorCount();
|
||||
assert( BaseClass::GetCtorCount() == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_WeakLink_NoConvert_Assert_NoPropagate_ptr w0;
|
||||
NonConstBase_WeakLink_NoConvert_Assert_NoPropagate_ptr w1;
|
||||
NonConstBase_StrongLink_NoConvert_NoCheck_NoPropagate_ptr s0;
|
||||
NonConstBase_StrongLink_NoConvert_NoCheck_NoPropagate_ptr s1;
|
||||
assert( !s0 );
|
||||
assert( !s1 );
|
||||
assert( s0 == s1 );
|
||||
assert( s1 == pNull );
|
||||
assert( s0 == pNull );
|
||||
assert( pNull == s0 );
|
||||
assert( pNull == s1 );
|
||||
assert( s1 == s0 );
|
||||
assert( s1 == s1 );
|
||||
assert( s0 == s0 );
|
||||
assert( s0 == s1 );
|
||||
assert( s1 <= s0 );
|
||||
assert( s1 >= s0 );
|
||||
assert( s0 <= s1 );
|
||||
assert( s0 >= s1 );
|
||||
assert( !( s1 < s0 ) );
|
||||
assert( !( s1 > s0 ) );
|
||||
assert( !( s0 < s1 ) );
|
||||
assert( !( s0 > s1 ) );
|
||||
assert( !w0 );
|
||||
assert( !w1 );
|
||||
assert( w0 == pNull );
|
||||
assert( s0 == pNull );
|
||||
assert( pNull == s0 );
|
||||
assert( pNull == w0 );
|
||||
assert( w0 == s0 );
|
||||
assert( w0 == w0 );
|
||||
assert( s0 == s0 );
|
||||
assert( s0 == w0 );
|
||||
assert( w0 <= s0 );
|
||||
assert( w0 >= s0 );
|
||||
assert( s0 <= w0 );
|
||||
assert( s0 >= w0 );
|
||||
assert( !( w0 < s0 ) );
|
||||
assert( !( w0 > s0 ) );
|
||||
assert( !( s0 < w0 ) );
|
||||
assert( !( s0 > w0 ) );
|
||||
assert( w0 == w1 );
|
||||
assert( w1 == pNull );
|
||||
assert( w0 == pNull );
|
||||
assert( pNull == w0 );
|
||||
assert( pNull == w1 );
|
||||
assert( w1 == w0 );
|
||||
assert( w1 == w1 );
|
||||
assert( w0 == w0 );
|
||||
assert( w0 == w1 );
|
||||
assert( w1 <= w0 );
|
||||
assert( w1 >= w0 );
|
||||
assert( w0 <= w1 );
|
||||
assert( w0 >= w1 );
|
||||
assert( !( w1 < w0 ) );
|
||||
assert( !( w1 > w0 ) );
|
||||
assert( !( w0 < w1 ) );
|
||||
assert( !( w0 > w1 ) );
|
||||
}
|
||||
assert( ctorCount == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount == BaseClass::GetDtorCount() );
|
||||
|
||||
{
|
||||
NonConstBase_WeakLink_NoConvert_Assert_NoPropagate_ptr w3( new BaseClass );
|
||||
NonConstBase_WeakLink_NoConvert_Assert_NoPropagate_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() );
|
||||
|
||||
{
|
||||
NonConstBase_StrongLink_NoConvert_NoCheck_NoPropagate_ptr s3( new BaseClass );
|
||||
NonConstBase_StrongLink_NoConvert_NoCheck_NoPropagate_ptr s4( new BaseClass );
|
||||
assert( s3 != s4 );
|
||||
assert( s3 );
|
||||
assert( s4 );
|
||||
s3 = s4;
|
||||
assert( s3 == s4 );
|
||||
assert( s3 );
|
||||
assert( s4 );
|
||||
assert( dtorCount + 3 == BaseClass::GetDtorCount() );
|
||||
}
|
||||
assert( ctorCount + 4 == BaseClass::GetCtorCount() );
|
||||
assert( dtorCount + 4 == BaseClass::GetDtorCount() );
|
||||
assert( BaseClass::GetCtorCount() == BaseClass::GetDtorCount() );
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoWeakCycleTests( void )
|
||||
{
|
||||
|
||||
const unsigned int ctorCountMoon = Moon::GetCtorCount();
|
||||
const unsigned int dtorCountMoon = Moon::GetDtorCount();
|
||||
assert( Moon::AllDestroyed() );
|
||||
const unsigned int ctorCountEarth = Earth::GetCtorCount();
|
||||
const unsigned int dtorCountEarth = Earth::GetDtorCount();
|
||||
assert( Earth::AllDestroyed() );
|
||||
|
||||
{
|
||||
Earth_WeakPtr ew0;
|
||||
Moon_WeakPtr mw0;
|
||||
}
|
||||
assert( Moon::AllDestroyed() );
|
||||
assert( Moon::GetCtorCount() == ctorCountMoon );
|
||||
assert( Moon::GetDtorCount() == dtorCountMoon );
|
||||
assert( Earth::AllDestroyed() );
|
||||
assert( Earth::GetCtorCount() == ctorCountEarth );
|
||||
assert( Earth::GetDtorCount() == dtorCountEarth );
|
||||
|
||||
{
|
||||
Earth_WeakPtr ew1( new Earth );
|
||||
}
|
||||
assert( Earth::AllDestroyed() );
|
||||
assert( Earth::GetCtorCount() == ctorCountEarth+1 );
|
||||
assert( Earth::GetDtorCount() == dtorCountEarth+1 );
|
||||
|
||||
{
|
||||
Moon_WeakPtr mw1( new Moon );
|
||||
}
|
||||
assert( Moon::AllDestroyed() );
|
||||
assert( Moon::GetCtorCount() == ctorCountMoon+1 );
|
||||
assert( Moon::GetDtorCount() == dtorCountMoon+1 );
|
||||
|
||||
{
|
||||
Earth_WeakPtr ew1( new Earth );
|
||||
Moon_WeakPtr mw1( new Moon );
|
||||
ew1->SetMoon( mw1 );
|
||||
}
|
||||
assert( Moon::AllDestroyed() );
|
||||
assert( Moon::GetCtorCount() == ctorCountMoon+2 );
|
||||
assert( Moon::GetDtorCount() == dtorCountMoon+2 );
|
||||
assert( Earth::AllDestroyed() );
|
||||
assert( Earth::GetCtorCount() == ctorCountEarth+2 );
|
||||
assert( Earth::GetDtorCount() == dtorCountEarth+2 );
|
||||
|
||||
{
|
||||
Earth_WeakPtr ew1( new Earth );
|
||||
Moon_WeakPtr mw1( new Moon );
|
||||
mw1->SetEarth( ew1 );
|
||||
}
|
||||
assert( Moon::AllDestroyed() );
|
||||
assert( Moon::GetCtorCount() == ctorCountMoon+3 );
|
||||
assert( Moon::GetDtorCount() == dtorCountMoon+3 );
|
||||
assert( Earth::AllDestroyed() );
|
||||
assert( Earth::GetCtorCount() == ctorCountEarth+3 );
|
||||
assert( Earth::GetDtorCount() == dtorCountEarth+3 );
|
||||
|
||||
{
|
||||
Earth_WeakPtr ew1( new Earth );
|
||||
Moon_WeakPtr mw1( new Moon );
|
||||
ew1->SetMoon( mw1 );
|
||||
mw1->SetEarth( ew1 );
|
||||
}
|
||||
assert( Moon::AllDestroyed() );
|
||||
assert( Moon::GetCtorCount() == ctorCountMoon+4 );
|
||||
assert( Moon::GetDtorCount() == dtorCountMoon+4 );
|
||||
assert( Earth::AllDestroyed() );
|
||||
assert( Earth::GetCtorCount() == ctorCountEarth+4 );
|
||||
assert( Earth::GetDtorCount() == dtorCountEarth+4 );
|
||||
|
||||
{
|
||||
Earth_StrongPtr es1( new Earth );
|
||||
Moon_StrongPtr ms1( new Moon );
|
||||
}
|
||||
assert( Moon::AllDestroyed() );
|
||||
assert( Moon::GetCtorCount() == ctorCountMoon+5 );
|
||||
assert( Moon::GetDtorCount() == dtorCountMoon+5 );
|
||||
assert( Earth::AllDestroyed() );
|
||||
assert( Earth::GetCtorCount() == ctorCountEarth+5 );
|
||||
assert( Earth::GetDtorCount() == dtorCountEarth+5 );
|
||||
|
||||
{
|
||||
Earth_StrongPtr es1( new Earth );
|
||||
Moon_StrongPtr ms1( new Moon );
|
||||
es1->SetMoon( ms1 );
|
||||
ms1->SetEarth( es1 );
|
||||
}
|
||||
assert( Moon::AllDestroyed() );
|
||||
assert( Moon::GetCtorCount() == ctorCountMoon+6 );
|
||||
assert( Moon::GetDtorCount() == dtorCountMoon+6 );
|
||||
assert( Earth::AllDestroyed() );
|
||||
assert( Earth::GetCtorCount() == ctorCountEarth+6 );
|
||||
assert( Earth::GetDtorCount() == dtorCountEarth+6 );
|
||||
|
||||
{
|
||||
Earth_StrongPtr es1( new Earth );
|
||||
Moon_StrongPtr ms1( new Moon );
|
||||
{
|
||||
Earth_WeakPtr ew1( es1 );
|
||||
Moon_WeakPtr mw1( ms1 );
|
||||
ew1->SetMoon( mw1 );
|
||||
mw1->SetEarth( ew1 );
|
||||
}
|
||||
// Note that dtor counts have not changed from previous test.
|
||||
assert( Moon::GetCtorCount() == ctorCountMoon+7 );
|
||||
assert( Moon::GetDtorCount() == dtorCountMoon+6 );
|
||||
assert( Earth::GetCtorCount() == ctorCountEarth+7 );
|
||||
assert( Earth::GetDtorCount() == dtorCountEarth+6 );
|
||||
}
|
||||
assert( Moon::AllDestroyed() );
|
||||
assert( Moon::GetCtorCount() == ctorCountMoon+7 );
|
||||
assert( Moon::GetDtorCount() == dtorCountMoon+7 );
|
||||
assert( Earth::AllDestroyed() );
|
||||
assert( Earth::GetCtorCount() == ctorCountEarth+7 );
|
||||
assert( Earth::GetDtorCount() == dtorCountEarth+7 );
|
||||
|
||||
{
|
||||
Earth_StrongPtr es1;
|
||||
Moon_StrongPtr ms1;
|
||||
{
|
||||
Earth_WeakPtr ew1( new Earth );
|
||||
Moon_WeakPtr mw1( new Moon );
|
||||
ew1->SetMoon( mw1 );
|
||||
mw1->SetEarth( ew1 );
|
||||
es1 = ew1;
|
||||
ms1 = mw1;
|
||||
}
|
||||
// Note that dtor counts have not changed from previous test.
|
||||
assert( Moon::GetCtorCount() == ctorCountMoon+8 );
|
||||
assert( Moon::GetDtorCount() == dtorCountMoon+7 );
|
||||
assert( Earth::GetCtorCount() == ctorCountEarth+8 );
|
||||
assert( Earth::GetDtorCount() == dtorCountEarth+7 );
|
||||
}
|
||||
assert( Moon::AllDestroyed() );
|
||||
assert( Moon::GetCtorCount() == ctorCountMoon+8 );
|
||||
assert( Moon::GetDtorCount() == dtorCountMoon+8 );
|
||||
assert( Earth::AllDestroyed() );
|
||||
assert( Earth::GetCtorCount() == ctorCountEarth+8 );
|
||||
assert( Earth::GetDtorCount() == dtorCountEarth+8 );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void DoStrongForwardReferenceTest( void )
|
||||
{
|
||||
/** @note These lines should cause the compiler to make a warning message
|
||||
about attempting to delete an undefined type. But it should not produce
|
||||
any error messages.
|
||||
*/
|
||||
Thingy_DeleteSingle_ptr p1;
|
||||
Thingy_DeleteSingle_ptr p2( p1 );
|
||||
Thingy_DeleteSingle_ptr p3;
|
||||
p3 = p1;
|
||||
|
||||
/** @note These lines should cause the compiler to make an error message
|
||||
about attempting to call the destructor for an undefined type.
|
||||
*/
|
||||
//Thingy_DeleteUsingFree_ptr p4;
|
||||
//Thingy_DeleteUsingFree_ptr p5( p4 );
|
||||
//Thingy_DeleteUsingFree_ptr p6;
|
||||
//p6 = p4;
|
||||
|
||||
/** @note These lines should cause the compiler to make neither a warning
|
||||
nor an error message even though the type is undefined.
|
||||
*/
|
||||
Thingy_DeleteNothing_ptr p7;
|
||||
Thingy_DeleteNothing_ptr p8( p7 );
|
||||
Thingy_DeleteNothing_ptr p9;
|
||||
p9 = p7;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
Loading…
Add table
Add a link
Reference in a new issue