//////////////////////////////////////////////////////////////////////////////// // 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 #include #include "base.h" // ---------------------------------------------------------------------------- using namespace std; 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 ); extern void DoLockedPtrTest( 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; #ifdef __GNUC__ #warning The warnings are by design: Check if SmartPtr can be used with a forward-reference. #endif typedef Loki::SmartPtr< Thingy, RefCounted, DisallowConversion, AssertCheck, DefaultSPStorage, PropagateConst > Thingy_DefaultStorage_ptr; typedef Loki::SmartPtr< Thingy, RefCounted, DisallowConversion, AssertCheck, HeapStorage, PropagateConst > Thingy_HeapStorage_ptr; // ---------------------------------------------------------------------------- /// @note Used for testing most policies. typedef Loki::SmartPtr< BaseClass, RefCounted, DisallowConversion, AssertCheck, DefaultSPStorage, DontPropagateConst > NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr; /// @note These 3 are used for testing const policies. typedef Loki::SmartPtr< const BaseClass, RefCounted, DisallowConversion, AssertCheck, DefaultSPStorage, DontPropagateConst > ConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr; typedef Loki::SmartPtr< const BaseClass, RefCounted, DisallowConversion, AssertCheck, DefaultSPStorage, PropagateConst > ConstBase_RefCount_NoConvert_Assert_Propagate_ptr; typedef Loki::SmartPtr< BaseClass, RefCounted, DisallowConversion, AssertCheck, DefaultSPStorage, PropagateConst > NonConstBase_RefCount_NoConvert_Assert_Propagate_ptr; // ---------------------------------------------------------------------------- /// @note These 5 are used for testing ownership policies. typedef Loki::SmartPtr< BaseClass, COMRefCounted, DisallowConversion, AssertCheck, DefaultSPStorage, DontPropagateConst > NonConstBase_ComRef_NoConvert_Assert_DontPropagate_ptr; typedef Loki::SmartPtr< BaseClass, RefLinked, DisallowConversion, AssertCheck, DefaultSPStorage, DontPropagateConst > NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr; typedef Loki::SmartPtr< BaseClass, DeepCopy, DisallowConversion, AssertCheck, DefaultSPStorage, DontPropagateConst > NonConstBase_DeepCopy_NoConvert_Assert_DontPropagate_ptr; typedef Loki::SmartPtr< BaseClass, DestructiveCopy, DisallowConversion, AssertCheck, DefaultSPStorage, DontPropagateConst > NonConstBase_KillCopy_NoConvert_Assert_DontPropagate_ptr; 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 > PublicSub_RefCount_NoConvert_Assert_DontPropagate_ptr; typedef Loki::SmartPtr< PrivateSubClass, RefCounted, DisallowConversion, AssertCheck, DefaultSPStorage, DontPropagateConst > 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 ) { NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p1; ConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p2( p1 ); ConstBase_RefCount_NoConvert_Assert_Propagate_ptr p3( p1 ); NonConstBase_RefCount_NoConvert_Assert_Propagate_ptr p4( p1 ); // p1 = p2; // illegal! converts const to non-const. // p1 = p3; // illegal! converts const to non-const. p1 = p4; // legal, but dubious. Changes const-propagation policy. p2 = p1; // legal. natural const conversion. p2 = p3; // legal, but dubious. Changes const-propagation policy. p2 = p4; // legal, but dubious. Changes const-propagation policy. p3 = p1; // legal, but dubious. Changes const-propagation policy. p3 = p2; // legal, but dubious. Changes const-propagation policy. p3 = p4; // legal. natural const conversion. p4 = p1; // legal, but dubious. Changes const-propagation policy. // p4 = p2; // illegal! converts const to non-const. // p4 = p3; // illegal! converts const to non-const. } // ---------------------------------------------------------------------------- void DoOwnershipConversionTests( void ) { NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p1; NonConstBase_ComRef_NoConvert_Assert_DontPropagate_ptr p2; NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p3; NonConstBase_DeepCopy_NoConvert_Assert_DontPropagate_ptr p4( new BaseClass ); NonConstBase_KillCopy_NoConvert_Assert_DontPropagate_ptr p5; NonConstBase_NoCopy_NoConvert_Assert_DontPropagate_ptr p6; // legal constructions. Each should allow copy with same policies. NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p7( p1 ); NonConstBase_ComRef_NoConvert_Assert_DontPropagate_ptr p8( p2 ); NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p9( p3 ); NonConstBase_DeepCopy_NoConvert_Assert_DontPropagate_ptr p10( p4 ); NonConstBase_KillCopy_NoConvert_Assert_DontPropagate_ptr p11( p5 ); // illegal construction! Can't copy anything with NoCopy policy. // NonConstBase_NoCopy_NoConvert_Assert_DontPropagate_ptr p12( p6 ); // illegal constructions! Can't convert from one ownership policy to another. // NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p13( p2 ); // NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p14( p3 ); // NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p15( p4 ); // NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p16( p5 ); // NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p17( p6 ); // illegal constructions! Can't convert from one ownership policy to another. // NonConstBase_ComRef_NoConvert_Assert_DontPropagate_ptr p18( p1 ); // NonConstBase_ComRef_NoConvert_Assert_DontPropagate_ptr p19( p3 ); // NonConstBase_ComRef_NoConvert_Assert_DontPropagate_ptr p20( p4 ); // NonConstBase_ComRef_NoConvert_Assert_DontPropagate_ptr p21( p5 ); // NonConstBase_ComRef_NoConvert_Assert_DontPropagate_ptr p22( p6 ); // illegal constructions! Can't convert from one ownership policy to another. // NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p23( p1 ); // NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p24( p2 ); // NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p25( p4 ); // NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p26( p5 ); // NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p27( p6 ); // illegal constructions! Can't convert from one ownership policy to another. // NonConstBase_DeepCopy_NoConvert_Assert_DontPropagate_ptr p28( p1 ); // NonConstBase_DeepCopy_NoConvert_Assert_DontPropagate_ptr p29( p2 ); // NonConstBase_DeepCopy_NoConvert_Assert_DontPropagate_ptr p30( p3 ); // NonConstBase_DeepCopy_NoConvert_Assert_DontPropagate_ptr p31( p5 ); // NonConstBase_DeepCopy_NoConvert_Assert_DontPropagate_ptr p32( p6 ); // illegal constructions! Can't convert from one ownership policy to another. // NonConstBase_KillCopy_NoConvert_Assert_DontPropagate_ptr p33( p1 ); // NonConstBase_KillCopy_NoConvert_Assert_DontPropagate_ptr p34( p2 ); // NonConstBase_KillCopy_NoConvert_Assert_DontPropagate_ptr p35( p3 ); // NonConstBase_KillCopy_NoConvert_Assert_DontPropagate_ptr p36( p4 ); // NonConstBase_KillCopy_NoConvert_Assert_DontPropagate_ptr p37( p6 ); // illegal constructions! Can't convert from one ownership policy to another. // NonConstBase_NoCopy_NoConvert_Assert_DontPropagate_ptr p38( p1 ); // NonConstBase_NoCopy_NoConvert_Assert_DontPropagate_ptr p39( p2 ); // NonConstBase_NoCopy_NoConvert_Assert_DontPropagate_ptr p40( p3 ); // NonConstBase_NoCopy_NoConvert_Assert_DontPropagate_ptr p41( p4 ); // NonConstBase_NoCopy_NoConvert_Assert_DontPropagate_ptr p42( p5 ); // illegal assignements! Can't convert from one ownership policy to another. // p1 = p2; // p1 = p3; // p1 = p4; // p1 = p5; // p1 = p6; // p2 = p1; // p2 = p3; // p2 = p4; // p2 = p5; // p2 = p6; // p3 = p1; // p3 = p2; // p3 = p4; // p3 = p5; // p3 = p6; // p4 = p1; // p4 = p2; // p4 = p3; // p4 = p5; // p4 = p6; // p5 = p1; // p5 = p2; // p5 = p3; // p5 = p4; // p5 = p6; // p6 = p1; // p6 = p2; // p6 = p3; // p6 = p4; // p6 = p5; } // ---------------------------------------------------------------------------- void DoInheritanceConversionTests( void ) { NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p1; PublicSub_RefCount_NoConvert_Assert_DontPropagate_ptr p2; PrivateSub_RefCount_NoConvert_Assert_DontPropagate_ptr p3; p1 = p2; // legal. Cast to public base class allowed. assert( p1 == p2 ); // p1 = p3; // illegal! Can't assign pointer since base class is private. // p2 = p1; // illegal! Can't do cast to derived class in pointer assignment. // p2 = p3; // illegal! Can't assign when types are unrelated. // p3 = p1; // illegal! Can't do cast to derived class in pointer assignment. // p3 = p2; // illegal! Can't assign when types are unrelated. NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p4( p2 ); assert( p4 == p1 ); assert( p4 == p2 ); // These copy-constructions are illegal for reasons shown above. // NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p5( p3 ); // PublicSub_RefCount_NoConvert_Assert_DontPropagate_ptr p6( p1 ); // PublicSub_RefCount_NoConvert_Assert_DontPropagate_ptr p7( p3 ); // PrivateSub_RefCount_NoConvert_Assert_DontPropagate_ptr p8( p1 ); // PrivateSub_RefCount_NoConvert_Assert_DontPropagate_ptr p9( p2 ); } // ---------------------------------------------------------------------------- void DoRefCountSwapTests( void ) { NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p1( new BaseClass ); NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p2( new BaseClass ); NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p3( p1 ); NonConstBase_RefCount_NoConvert_Assert_DontPropagate_ptr p4( p2 ); // p1 == p3 and p2 == p4 assert( p1 == p3 ); assert( p1 != p2 ); assert( p1 != p4 ); assert( p2 == p4 ); assert( p2 != p3 ); assert( p2 != p1 ); // p1 == p4 and p2 == p3 p3.Swap( p4 ); assert( p1 == p4 ); assert( p1 != p2 ); assert( p1 != p3 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p1 ); // p1 == p3 and p2 == p4 p3.Swap( p4 ); assert( p1 == p3 ); assert( p1 != p2 ); assert( p1 != p4 ); assert( p2 == p4 ); assert( p2 != p3 ); assert( p2 != p1 ); // p2 == p3 and p1 == p4 p1.Swap( p2 ); assert( p1 == p4 ); assert( p1 != p2 ); assert( p1 != p3 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p1 ); // p2 == p3 and p1 == p4 p1.Swap( p1 ); assert( p1 == p4 ); assert( p1 != p2 ); assert( p1 != p3 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p1 ); // p2 == p3 and p4 == p1 p1.Swap( p4 ); assert( p1 == p4 ); assert( p1 != p2 ); assert( p1 != p3 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p1 ); } // ---------------------------------------------------------------------------- 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 ); NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p5; NonConstBase_RefLink_NoConvert_Assert_DontPropagate_ptr p6( new BaseClass ); // p1 <---> p3 and p2 <---> p4 and p5 and p6 assert( p1 == p3 ); assert( p1 != p2 ); assert( p1 != p4 ); assert( p2 == p4 ); assert( p2 != p3 ); assert( p2 != p1 ); assert( p1 != p5 ); assert( p2 != p5 ); assert( p3 != p5 ); assert( p4 != p5 ); assert( p1 == p1 ); assert( p2 == p2 ); assert( p3 == p3 ); assert( p4 == p4 ); assert( p5 == p5 ); p3.Swap( p4 ); // p1 <---> p4 and p2 <---> p3 and p5 and p6 assert( p1 == p4 ); assert( p1 != p2 ); assert( p1 != p3 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p1 ); assert( p1 != p5 ); assert( p2 != p5 ); assert( p3 != p5 ); assert( p4 != p5 ); assert( p1 == p1 ); assert( p2 == p2 ); assert( p3 == p3 ); assert( p4 == p4 ); assert( p5 == p5 ); p3.Swap( p4 ); // p1 <---> p3 and p2 <---> p4 and p5 and p6 assert( p1 == p3 ); assert( p1 != p2 ); assert( p1 != p4 ); assert( p2 == p4 ); assert( p2 != p3 ); assert( p2 != p1 ); assert( p1 != p5 ); assert( p2 != p5 ); assert( p3 != p5 ); assert( p4 != p5 ); assert( p1 == p1 ); assert( p2 == p2 ); assert( p3 == p3 ); assert( p4 == p4 ); 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 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p1 ); assert( p1 != p5 ); assert( p2 != p5 ); assert( p3 != p5 ); assert( p4 != p5 ); assert( p1 == p1 ); assert( p2 == p2 ); assert( p3 == p3 ); assert( p4 == p4 ); assert( p5 == p5 ); p1.Swap( p1 ); // p2 <---> p3 and p1 <---> p4 and p5 and p6 assert( p1 == p4 ); assert( p1 != p2 ); assert( p1 != p3 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p1 ); assert( p1 != p5 ); assert( p2 != p5 ); assert( p3 != p5 ); assert( p4 != p5 ); assert( p1 == p1 ); assert( p2 == p2 ); assert( p3 == p3 ); assert( p4 == p4 ); assert( p5 == p5 ); p1.Swap( p4 ); // p2 <---> p3 and p4 <---> p1 and p5 and p6 assert( p1 == p4 ); assert( p1 != p2 ); assert( p1 != p3 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p1 ); assert( p1 != p5 ); assert( p2 != p5 ); assert( p3 != p5 ); assert( p4 != p5 ); assert( p1 == p1 ); assert( p2 == p2 ); assert( p3 == p3 ); assert( p4 == p4 ); assert( p5 == p5 ); p4.Swap( p1 ); // p2 <---> p3 and p4 <---> p1 and p5 and p6 assert( p1 == p4 ); assert( p1 != p2 ); assert( p1 != p3 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p1 ); assert( p1 != p5 ); assert( p2 != p5 ); assert( p3 != p5 ); assert( p4 != p5 ); assert( p1 == p1 ); assert( p2 == p2 ); assert( p3 == p3 ); assert( p4 == p4 ); assert( p5 == p5 ); p5.Swap( p5 ); // p2 <---> p3 and p4 <---> p1 and p5 and p6 assert( p1 == p1 ); assert( p2 == p2 ); assert( p3 == p3 ); assert( p4 == p4 ); assert( p1 != p5 ); assert( p2 != p5 ); assert( p3 != p5 ); assert( p4 != p5 ); p5.Swap( p1 ); // p2 <---> p3 and p4 <---> p5 and p1 and p6 assert( p5 == p4 ); assert( p5 != p2 ); assert( p5 != p3 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p5 ); assert( p1 != p5 ); assert( p2 != p1 ); assert( p3 != p1 ); assert( p4 != p1 ); assert( p1 == p1 ); assert( p2 == p2 ); assert( p3 == p3 ); assert( p4 == p4 ); assert( p5 == p5 ); p6.Swap( p1 ); // p2 <---> p3 and p4 <---> p5 and p1 and p6 assert( p5 == p4 ); assert( p5 != p2 ); assert( p5 != p3 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p5 ); assert( p1 != p5 ); assert( p2 != p1 ); assert( p3 != p1 ); assert( p4 != p1 ); assert( p1 == p1 ); assert( p2 == p2 ); assert( p3 == p3 ); assert( p4 == p4 ); assert( p5 == p5 ); assert( p6 == p6 ); p5.Swap( p1 ); // p2 <---> p3 and p4 <---> p1 and p5 and p6 assert( p1 == p4 ); assert( p1 != p2 ); assert( p1 != p3 ); assert( p2 == p3 ); assert( p2 != p4 ); assert( p2 != p1 ); assert( p1 != p5 ); assert( p2 != p5 ); assert( p3 != p5 ); assert( p4 != p5 ); assert( p1 == p1 ); assert( p2 == p2 ); assert( p3 == p3 ); assert( p4 == p4 ); assert( p5 == p5 ); p6 = p2; // p6 <---> p2 <---> p3 and p4 <---> p1 and p5 assert( p6 == p2 ); assert( p6 == p3 ); assert( p2 == p3 ); assert( p1 == p4 ); assert( p5 != p3 ); assert( p2 != p4 ); assert( p2 != p5 ); 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 ); p5 = p3; // p6 <---> p2 <---> p3 <---> p5 and p4 <---> p1 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 ); p5.Swap( p3 ); // p6 <---> p2 <---> p5 <---> p3 and p4 <---> p1 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 ); p2.Swap( p3 ); // p6 <---> p3 <---> p5 <---> p2 and p4 <---> p1 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 ); 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(); (void) ctorCount; const unsigned int dtorCount = BaseClass::GetDtorCount(); (void) dtorCount; 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() ); w3->DoThat(); } assert( ctorCount + 2 == BaseClass::GetCtorCount() ); assert( dtorCount + 2 == BaseClass::GetDtorCount() ); assert( BaseClass::GetCtorCount() == BaseClass::GetDtorCount() ); } // ---------------------------------------------------------------------------- void DoRefCountNullPointerTests( void ) { BaseClass * pNull = NULL; (void) pNull; const unsigned int ctorCount = BaseClass::GetCtorCount(); (void) ctorCount; const unsigned int dtorCount = BaseClass::GetDtorCount(); (void) dtorCount; 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; (void) pNull; const unsigned int ctorCount = BaseClass::GetCtorCount(); (void) ctorCount; const unsigned int dtorCount = BaseClass::GetDtorCount(); (void) dtorCount; 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() ); } // ---------------------------------------------------------------------------- void DoComRefTest( void ) { const unsigned int ctorCount = MimicCOM::GetCtorCount(); (void) ctorCount; const unsigned int dtorCount = MimicCOM::GetDtorCount(); (void) dtorCount; assert( MimicCOM::AllDestroyed() ); { MimicCOM_ptr p1; } assert( MimicCOM::AllDestroyed() ); assert( ctorCount == MimicCOM::GetCtorCount() ); assert( dtorCount == MimicCOM::GetDtorCount() ); { MimicCOM_ptr p1( MimicCOM::QueryInterface() ); } assert( ctorCount+1 == MimicCOM::GetCtorCount() ); assert( dtorCount+1 == MimicCOM::GetDtorCount() ); { MimicCOM_ptr p2( MimicCOM::QueryInterface() ); 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(); DoStrongReleaseTests(); DoStrongReleaseTests(); DoWeakCycleTests(); DoForwardReferenceTest(); DoStrongForwardReferenceTest(); DoRefCountNullPointerTests(); DoRefLinkNullPointerTests(); DoRefCountSwapTests(); DoRefLinkSwapTests(); DoComRefTest(); DoStrongConstTests(); DoConstConversionTests(); DoOwnershipConversionTests(); DoInheritanceConversionTests(); DoLockedPtrTest(); // Check that nothing was leaked. assert( BaseClass::AllDestroyed() ); assert( !BaseClass::ExtraConstructions() ); // Check that no destructor called too often. assert( !BaseClass::ExtraDestructions() ); cout << "All SmartPtr tests passed!" << endl; return 0; } // ---------------------------------------------------------------------------- // $Log$ // Revision 1.9 2006/05/30 14:17:05 syntheticpp // don't confuse with warnings // // Revision 1.8 2006/05/18 05:05:21 rich_sposato // Added QueryInterface function to MimicCOM class. // // Revision 1.7 2006/04/28 00:34:21 rich_sposato // Added test for thread-safe StrongPtr policy. // // Revision 1.6 2006/04/16 14:05:39 syntheticpp // remove warnings // // 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 // // 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. // // Revision 1.1 2006/02/25 01:53:20 rich_sposato // Added test project for Loki::SmartPtr class. //