Added tests for dynamic-casting with SmartPtr and StrongPtr.
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@1053 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
9e3a736929
commit
6eb3a5a216
2 changed files with 420 additions and 22 deletions
|
@ -35,6 +35,7 @@ extern void DoWeakCycleTests( void );
|
||||||
extern void DoStrongConstTests( void );
|
extern void DoStrongConstTests( void );
|
||||||
extern void DoStrongForwardReferenceTest( void );
|
extern void DoStrongForwardReferenceTest( void );
|
||||||
extern void DoStrongCompareTests( void );
|
extern void DoStrongCompareTests( void );
|
||||||
|
extern void DoStrongPtrDynamicCastTests( void );
|
||||||
|
|
||||||
extern void DoLockedPtrTest( void );
|
extern void DoLockedPtrTest( void );
|
||||||
extern void DoLockedStorageTest( void );
|
extern void DoLockedStorageTest( void );
|
||||||
|
@ -1113,6 +1114,122 @@ void DoForwardReferenceTest( void )
|
||||||
//p6 = p5;
|
//p6 = p5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
class Feline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Feline() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Lion : public Feline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Lion() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Tiger : public Feline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Tiger() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Dog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Dog() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void DoSmartPtrDynamicCastTests( void )
|
||||||
|
{
|
||||||
|
typedef ::Loki::SmartPtr< Feline > FelinePtr;
|
||||||
|
typedef ::Loki::SmartPtr< Lion > LionPtr;
|
||||||
|
typedef ::Loki::SmartPtr< Tiger > TigerPtr;
|
||||||
|
typedef ::Loki::SmartPtr< Dog > DogPtr;
|
||||||
|
|
||||||
|
Feline * feline = new Lion;
|
||||||
|
Lion * lion = new Lion;
|
||||||
|
Tiger * tiger = new Tiger;
|
||||||
|
Dog * dog = new Dog;
|
||||||
|
|
||||||
|
FelinePtr pFeline( feline );
|
||||||
|
LionPtr pLion( lion );
|
||||||
|
TigerPtr pTiger( tiger );
|
||||||
|
DogPtr pDog( dog );
|
||||||
|
|
||||||
|
// This is legal because C++ allows an automatic down-cast to public base class.
|
||||||
|
pFeline = pLion;
|
||||||
|
|
||||||
|
#ifdef CHECK_TYPE_CAST
|
||||||
|
pLion = pFeline; // Fails as the compiler cannot convert pointers in SmartPtr
|
||||||
|
#endif // CHECK_TYPE_CAST
|
||||||
|
|
||||||
|
assert( pFeline );
|
||||||
|
// Can up-cast from feline to lion only if the feline is a lion.
|
||||||
|
pLion.DynamicCastFrom( pFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to tiger since although these are both types of felines,
|
||||||
|
// they are not related to one another.
|
||||||
|
pTiger.DynamicCastFrom( pLion );
|
||||||
|
assert( !pTiger );
|
||||||
|
|
||||||
|
// Can't cast from dog to lion since a dog is not a type of feline.
|
||||||
|
pLion.DynamicCastFrom( pDog );
|
||||||
|
assert( !pLion );
|
||||||
|
|
||||||
|
pLion.DynamicCastFrom( pFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to dog since these animal types are not related.
|
||||||
|
pDog.DynamicCastFrom( pLion );
|
||||||
|
assert( !pDog );
|
||||||
|
|
||||||
|
feline = new Lion;
|
||||||
|
lion = new Lion;
|
||||||
|
tiger = new Tiger;
|
||||||
|
dog = new Dog;
|
||||||
|
|
||||||
|
// Now do tests when converting from const pointers.
|
||||||
|
const FelinePtr pcFeline( feline );
|
||||||
|
const LionPtr pcLion( lion );
|
||||||
|
const TigerPtr pcTiger( tiger );
|
||||||
|
const DogPtr pcDog( dog );
|
||||||
|
|
||||||
|
assert( pcFeline );
|
||||||
|
// Can up-cast from feline to lion only if the feline is a lion.
|
||||||
|
pLion.DynamicCastFrom( pcFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pcFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to tiger since although these are both types of felines,
|
||||||
|
// they are not related to one another.
|
||||||
|
pTiger.DynamicCastFrom( pcLion );
|
||||||
|
assert( !pTiger );
|
||||||
|
|
||||||
|
// Can't cast from dog to lion since a dog is not a type of feline.
|
||||||
|
pLion.DynamicCastFrom( pcDog );
|
||||||
|
assert( !pLion );
|
||||||
|
|
||||||
|
pLion.DynamicCastFrom( pcFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pcFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to dog since these animal types are not related.
|
||||||
|
pDog.DynamicCastFrom( pcLion );
|
||||||
|
assert( !pDog );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
int main( int argc, const char * argv[] )
|
int main( int argc, const char * argv[] )
|
||||||
{
|
{
|
||||||
|
@ -1146,6 +1263,8 @@ int main( int argc, const char * argv[] )
|
||||||
DoConstConversionTests();
|
DoConstConversionTests();
|
||||||
DoOwnershipConversionTests();
|
DoOwnershipConversionTests();
|
||||||
DoInheritanceConversionTests();
|
DoInheritanceConversionTests();
|
||||||
|
DoSmartPtrDynamicCastTests();
|
||||||
|
DoStrongPtrDynamicCastTests();
|
||||||
|
|
||||||
#if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING)
|
#if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING)
|
||||||
if ( doThreadTest )
|
if ( doThreadTest )
|
||||||
|
|
|
@ -1186,6 +1186,285 @@ void DoStrongCompareTests( void )
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
class Feline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Feline() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Lion : public Feline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Lion() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Tiger : public Feline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Tiger() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Dog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Dog() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void DoStrongPtrDynamicCastTests( void )
|
||||||
|
{
|
||||||
|
typedef ::Loki::StrongPtr< Feline, true, ::Loki::TwoRefCounts > FelineCountPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Tiger, true, ::Loki::TwoRefCounts > TigerCountPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Lion, true, ::Loki::TwoRefCounts > LionCountPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Dog, true, ::Loki::TwoRefCounts > DogCountPtr;
|
||||||
|
|
||||||
|
typedef ::Loki::StrongPtr< Feline, true, ::Loki::LockableTwoRefCounts > FelineLockPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Tiger, true, ::Loki::LockableTwoRefCounts > TigerLockPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Lion, true, ::Loki::LockableTwoRefCounts > LionLockPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Dog, true, ::Loki::LockableTwoRefCounts > DogLockPtr;
|
||||||
|
|
||||||
|
typedef ::Loki::StrongPtr< Feline, true, ::Loki::TwoRefLinks > FelineLinksPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Tiger, true, ::Loki::TwoRefLinks > TigerLinksPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Lion, true, ::Loki::TwoRefLinks > LionLinksPtr;
|
||||||
|
typedef ::Loki::StrongPtr< Dog, true, ::Loki::TwoRefLinks > DogLinksPtr;
|
||||||
|
|
||||||
|
{
|
||||||
|
Feline * feline = new Lion;
|
||||||
|
Tiger * tiger = new Tiger;
|
||||||
|
Lion * lion = new Lion;
|
||||||
|
Dog * dog = new Dog;
|
||||||
|
|
||||||
|
FelineCountPtr pFeline( feline );
|
||||||
|
TigerCountPtr pTiger( tiger );
|
||||||
|
LionCountPtr pLion( lion );
|
||||||
|
DogCountPtr pDog( dog );
|
||||||
|
|
||||||
|
// This is legal because C++ allows an automatic down-cast to public base class.
|
||||||
|
pFeline = pLion;
|
||||||
|
|
||||||
|
#ifdef CHECK_TYPE_CAST
|
||||||
|
pLion = pFeline; // Fails as the compiler cannot convert pointers in SmartPtr
|
||||||
|
#endif // CHECK_TYPE_CAST
|
||||||
|
|
||||||
|
assert( pFeline );
|
||||||
|
// Can up-cast from feline to lion only if the feline is a lion.
|
||||||
|
pLion.DynamicCastFrom( pFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to tiger since although these are both types of felines,
|
||||||
|
// they are not related to one another.
|
||||||
|
pTiger.DynamicCastFrom( pLion );
|
||||||
|
assert( !pTiger );
|
||||||
|
|
||||||
|
// Can't cast from dog to lion since a dog is not a type of feline.
|
||||||
|
pLion.DynamicCastFrom( pDog );
|
||||||
|
assert( !pLion );
|
||||||
|
|
||||||
|
pLion.DynamicCastFrom( pFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to dog since these animal types are not related.
|
||||||
|
pDog.DynamicCastFrom( pLion );
|
||||||
|
assert( !pDog );
|
||||||
|
|
||||||
|
feline = new Lion;
|
||||||
|
lion = new Lion;
|
||||||
|
tiger = new Tiger;
|
||||||
|
dog = new Dog;
|
||||||
|
|
||||||
|
// Now do tests when converting from const pointers.
|
||||||
|
const FelineCountPtr pcFeline( feline );
|
||||||
|
const TigerCountPtr pcTiger( tiger );
|
||||||
|
const LionCountPtr pcLion( lion );
|
||||||
|
const DogCountPtr pcDog( dog );
|
||||||
|
|
||||||
|
assert( pcFeline );
|
||||||
|
// Can up-cast from feline to lion only if the feline is a lion.
|
||||||
|
pLion.DynamicCastFrom( pcFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pcFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to tiger since although these are both types of felines,
|
||||||
|
// they are not related to one another.
|
||||||
|
pTiger.DynamicCastFrom( pcLion );
|
||||||
|
assert( !pTiger );
|
||||||
|
|
||||||
|
// Can't cast from dog to lion since a dog is not a type of feline.
|
||||||
|
pLion.DynamicCastFrom( pcDog );
|
||||||
|
assert( !pLion );
|
||||||
|
|
||||||
|
pLion.DynamicCastFrom( pcFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pcFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to dog since these animal types are not related.
|
||||||
|
pDog.DynamicCastFrom( pcLion );
|
||||||
|
assert( !pDog );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Feline * feline = new Lion;
|
||||||
|
Tiger * tiger = new Tiger;
|
||||||
|
Lion * lion = new Lion;
|
||||||
|
Dog * dog = new Dog;
|
||||||
|
|
||||||
|
FelineLockPtr pFeline( feline );
|
||||||
|
TigerLockPtr pTiger( tiger );
|
||||||
|
LionLockPtr pLion( lion );
|
||||||
|
DogLockPtr pDog( dog );
|
||||||
|
|
||||||
|
// This is legal because C++ allows an automatic down-cast to public base class.
|
||||||
|
pFeline = pLion;
|
||||||
|
|
||||||
|
#ifdef CHECK_TYPE_CAST
|
||||||
|
pLion = pFeline; // Fails as the compiler cannot convert pointers in SmartPtr
|
||||||
|
#endif // CHECK_TYPE_CAST
|
||||||
|
|
||||||
|
assert( pFeline );
|
||||||
|
// Can up-cast from feline to lion only if the feline is a lion.
|
||||||
|
pLion.DynamicCastFrom( pFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to tiger since although these are both types of felines,
|
||||||
|
// they are not related to one another.
|
||||||
|
pTiger.DynamicCastFrom( pLion );
|
||||||
|
assert( !pTiger );
|
||||||
|
|
||||||
|
// Can't cast from dog to lion since a dog is not a type of feline.
|
||||||
|
pLion.DynamicCastFrom( pDog );
|
||||||
|
assert( !pLion );
|
||||||
|
|
||||||
|
pLion.DynamicCastFrom( pFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to dog since these animal types are not related.
|
||||||
|
pDog.DynamicCastFrom( pLion );
|
||||||
|
assert( !pDog );
|
||||||
|
|
||||||
|
feline = new Lion;
|
||||||
|
tiger = new Tiger;
|
||||||
|
lion = new Lion;
|
||||||
|
dog = new Dog;
|
||||||
|
|
||||||
|
// Now do tests when converting from const pointers.
|
||||||
|
const FelineLockPtr pcFeline( feline );
|
||||||
|
const TigerLockPtr pcTiger( tiger );
|
||||||
|
const LionLockPtr pcLion( lion );
|
||||||
|
const DogLockPtr pcDog( dog );
|
||||||
|
|
||||||
|
assert( pcFeline );
|
||||||
|
// Can up-cast from feline to lion only if the feline is a lion.
|
||||||
|
pLion.DynamicCastFrom( pcFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pcFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to tiger since although these are both types of felines,
|
||||||
|
// they are not related to one another.
|
||||||
|
pTiger.DynamicCastFrom( pcLion );
|
||||||
|
assert( !pTiger );
|
||||||
|
|
||||||
|
// Can't cast from dog to lion since a dog is not a type of feline.
|
||||||
|
pLion.DynamicCastFrom( pcDog );
|
||||||
|
assert( !pLion );
|
||||||
|
|
||||||
|
pLion.DynamicCastFrom( pcFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pcFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to dog since these animal types are not related.
|
||||||
|
pDog.DynamicCastFrom( pcLion );
|
||||||
|
assert( !pDog );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Feline * feline = new Lion;
|
||||||
|
Tiger * tiger = new Tiger;
|
||||||
|
Lion * lion = new Lion;
|
||||||
|
Dog * dog = new Dog;
|
||||||
|
|
||||||
|
FelineLinksPtr pFeline( feline );
|
||||||
|
TigerLinksPtr pTiger( tiger );
|
||||||
|
LionLinksPtr pLion( lion );
|
||||||
|
DogLinksPtr pDog( dog );
|
||||||
|
|
||||||
|
// This is legal because C++ allows an automatic down-cast to public base class.
|
||||||
|
pFeline = pLion;
|
||||||
|
|
||||||
|
#ifdef CHECK_TYPE_CAST
|
||||||
|
pLion = pFeline; // Fails as the compiler cannot convert pointers in SmartPtr
|
||||||
|
#endif // CHECK_TYPE_CAST
|
||||||
|
|
||||||
|
assert( pFeline );
|
||||||
|
// Can up-cast from feline to lion only if the feline is a lion.
|
||||||
|
pLion.DynamicCastFrom( pFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to tiger since although these are both types of felines,
|
||||||
|
// they are not related to one another.
|
||||||
|
pTiger.DynamicCastFrom( pLion );
|
||||||
|
assert( !pTiger );
|
||||||
|
|
||||||
|
// Can't cast from dog to lion since a dog is not a type of feline.
|
||||||
|
pLion.DynamicCastFrom( pDog );
|
||||||
|
assert( !pLion );
|
||||||
|
|
||||||
|
pLion.DynamicCastFrom( pFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to dog since these animal types are not related.
|
||||||
|
pDog.DynamicCastFrom( pLion );
|
||||||
|
assert( !pDog );
|
||||||
|
|
||||||
|
feline = new Lion;
|
||||||
|
tiger = new Tiger;
|
||||||
|
lion = new Lion;
|
||||||
|
dog = new Dog;
|
||||||
|
|
||||||
|
// Now do tests when converting from const pointers.
|
||||||
|
const FelineLinksPtr pcFeline( feline );
|
||||||
|
const TigerLinksPtr pcTiger( tiger );
|
||||||
|
const LionLinksPtr pcLion( lion );
|
||||||
|
const DogLinksPtr pcDog( dog );
|
||||||
|
|
||||||
|
assert( pcFeline );
|
||||||
|
// Can up-cast from feline to lion only if the feline is a lion.
|
||||||
|
pLion.DynamicCastFrom( pcFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pcFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to tiger since although these are both types of felines,
|
||||||
|
// they are not related to one another.
|
||||||
|
pTiger.DynamicCastFrom( pcLion );
|
||||||
|
assert( !pTiger );
|
||||||
|
|
||||||
|
// Can't cast from dog to lion since a dog is not a type of feline.
|
||||||
|
pLion.DynamicCastFrom( pcDog );
|
||||||
|
assert( !pLion );
|
||||||
|
|
||||||
|
pLion.DynamicCastFrom( pcFeline );
|
||||||
|
assert( pLion );
|
||||||
|
assert( pLion == pcFeline );
|
||||||
|
|
||||||
|
// Can't cast from lion to dog since these animal types are not related.
|
||||||
|
pDog.DynamicCastFrom( pcLion );
|
||||||
|
assert( !pDog );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
// GCC bug
|
// GCC bug
|
||||||
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38579
|
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38579
|
||||||
|
@ -1193,30 +1472,30 @@ void DoStrongCompareTests( void )
|
||||||
struct Policy
|
struct Policy
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Policy() {}
|
Policy() {}
|
||||||
Policy(const Policy&) {}
|
Policy(const Policy&) {}
|
||||||
int i;
|
int i;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int I, class P>
|
template<int I, class P>
|
||||||
struct BugGcc :
|
struct BugGcc :
|
||||||
//protected P
|
//protected P
|
||||||
public P
|
public P
|
||||||
{
|
{
|
||||||
BugGcc() {}
|
BugGcc() {}
|
||||||
|
|
||||||
template<int I2, class P2>
|
template<int I2, class P2>
|
||||||
BugGcc(const BugGcc<I2, P2>& t) : P(t) {}
|
BugGcc(const BugGcc<I2, P2>& t) : P(t) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
void foo()
|
void foo()
|
||||||
{
|
{
|
||||||
BugGcc<0, Policy> f1;
|
BugGcc<0, Policy> f1;
|
||||||
BugGcc<1, Policy> f2(f1);
|
BugGcc<1, Policy> f2(f1);
|
||||||
|
|
||||||
// Policy members are still not public,
|
// Policy members are still not public,
|
||||||
// this will not compile:
|
// this will not compile:
|
||||||
//int i = f1.i;
|
//int i = f1.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue