Implemented patch 2893162 to allow dynamic-casting with SmartPtr and StrongPtr.

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@1052 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
rich_sposato 2009-11-10 19:22:16 +00:00
parent d54996dbba
commit 9e3a736929
3 changed files with 242 additions and 36 deletions

View file

@ -194,9 +194,9 @@ namespace Loki
// Destroys the data stored
// (Destruction might be taken over by the OwnershipPolicy)
//
// If your compiler gives you a warning in this area while
// compiling the tests, it is on purpose, please ignore it.
//
// If your compiler gives you a warning in this area while
// compiling the tests, it is on purpose, please ignore it.
void Destroy()
{
delete pointee_;
@ -1172,6 +1172,45 @@ namespace Loki
typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg;
#endif
/// SmartPtr uses this helper class to specify the dynamic-caster constructor.
class DynamicCastHelper {};
/// Private constructor is only used for dynamic-casting.
template
<
typename T1,
template < class > class OP1,
class CP1,
template < class > class KP1,
template < class > class SP1,
template < class > class CNP1
>
SmartPtr( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs, const DynamicCastHelper & helper )
{
(void)helper; // do void cast to remove compiler warning.
// Dynamic casting from T1 to T and saving result in `this''s pointer
PointerType p = dynamic_cast< PointerType >( GetImplRef( rhs ) );
GetImplRef( *this ) = OP::Clone( p );
}
/// Private constructor is only used for dynamic-casting.
template
<
typename T1,
template < class > class OP1,
class CP1,
template < class > class KP1,
template < class > class SP1,
template < class > class CNP1
>
SmartPtr( SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs, const DynamicCastHelper & helper )
{
(void)helper; // do void cast to remove compiler warning.
// Dynamic casting from T1 to T and saving result in `this''s pointer
PointerType p = dynamic_cast< PointerType >( GetImplRef( rhs ) );
GetImplRef( *this ) = OP::Clone( p );
}
public:
SmartPtr()
@ -1206,7 +1245,9 @@ namespace Loki
>
SmartPtr(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{ GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
{
GetImplRef(*this) = OP::Clone(GetImplRef(rhs));
}
template
<
@ -1285,6 +1326,40 @@ namespace Loki
}
}
/// Dynamically-casts parameter pointer to the type specified by this SmartPtr type.
template
<
typename T1,
template < class > class OP1,
class CP1,
template < class > class KP1,
template < class > class SP1,
template < class > class CNP1
>
SmartPtr & DynamicCastFrom( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
{
SmartPtr temp( rhs, DynamicCastHelper() );
temp.Swap( *this );
return *this;
}
/// Dynamically-casts parameter pointer to the type specified by this SmartPtr type.
template
<
typename T1,
template < class > class OP1,
class CP1,
template < class > class KP1,
template < class > class SP1,
template < class > class CNP1
>
SmartPtr & DynamicCastFrom( SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
{
SmartPtr temp( rhs, DynamicCastHelper() );
temp.Swap( *this );
return *this;
}
#ifdef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
// old non standard in class definition of friends