|
From: <ric...@us...> - 2009-11-10 19:22:24
|
Revision: 1052
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1052&view=rev
Author: rich_sposato
Date: 2009-11-10 19:22:16 +0000 (Tue, 10 Nov 2009)
Log Message:
-----------
Implemented patch 2893162 to allow dynamic-casting with SmartPtr and StrongPtr.
Modified Paths:
--------------
trunk/include/loki/SmartPtr.h
trunk/include/loki/StrongPtr.h
trunk/src/StrongPtr.cpp
Modified: trunk/include/loki/SmartPtr.h
===================================================================
--- trunk/include/loki/SmartPtr.h 2009-11-02 22:45:51 UTC (rev 1051)
+++ trunk/include/loki/SmartPtr.h 2009-11-10 19:22:16 UTC (rev 1052)
@@ -194,9 +194,9 @@
// 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 @@
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 @@
>
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 @@
}
}
+ /// 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
Modified: trunk/include/loki/StrongPtr.h
===================================================================
--- trunk/include/loki/StrongPtr.h 2009-11-02 22:45:51 UTC (rev 1051)
+++ trunk/include/loki/StrongPtr.h 2009-11-10 19:22:16 UTC (rev 1052)
@@ -564,6 +564,8 @@
Increment( strong );
}
+ TwoRefCounts( const TwoRefCounts & rhs, bool isNull, bool strong );
+
/** The destructor does not need to do anything since the call to
ZapPointer inside StrongPtr::~StrongPtr will do the cleanup which
this dtor would have done.
@@ -664,6 +666,24 @@
Increment( strong );
}
+ LockableTwoRefCounts( const LockableTwoRefCounts & rhs, bool isNull, bool strong ) :
+ m_counts( ( isNull ) ? NULL : rhs.m_counts )
+ {
+ if ( isNull )
+ {
+ void * temp = ThreadSafePointerAllocator::operator new(
+ sizeof(Loki::Private::LockableTwoRefCountInfo) );
+#ifdef DO_EXTRA_LOKI_TESTS
+ assert( temp != 0 );
+#endif
+ m_counts = new ( temp ) Loki::Private::LockableTwoRefCountInfo( strong );
+ }
+ else
+ {
+ Increment( strong );
+ }
+ }
+
/** The destructor does not need to do anything since the call to
ZapPointer inside StrongPtr::~StrongPtr will do the cleanup which
this dtor would have done.
@@ -789,6 +809,8 @@
TwoRefLinks( const TwoRefLinks & rhs, bool strong );
+ TwoRefLinks( const TwoRefLinks & rhs, bool isNull, bool strong );
+
bool Release( bool strong );
void Swap( TwoRefLinks & rhs );
@@ -893,6 +915,49 @@
typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg;
#endif
+ /// StrongPtr uses this helper class to specify the dynamic-caster constructor.
+ class DynamicCastHelper {};
+
+ /// Private constructor is only used for dynamic-casting.
+ template
+ <
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
+ StrongPtr( const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs,
+ bool isNull, const DynamicCastHelper & helper )
+ // Dynamic casting from T1 to T and saving result in ownership policy.
+ : OP( rhs, isNull, Strong )
+ {
+ (void)helper; // do void cast to remove compiler warning.
+ }
+
+ /// Private constructor is only used for dynamic-casting.
+ template
+ <
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
+ StrongPtr( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs,
+ bool isNull, const DynamicCastHelper & helper )
+ // Dynamic casting from T1 to T and saving result in ownership policy.
+ : OP( rhs, isNull, Strong )
+ {
+ (void)helper; // do void cast to remove compiler warning.
+ }
+
public:
StrongPtr( void ) : OP( Strong )
@@ -1032,6 +1097,56 @@
}
}
+ /// Dynamically-casts parameter pointer to the type specified by this SmartPtr type.
+ template
+ <
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
+ StrongPtr & DynamicCastFrom( const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
+ {
+ typedef typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::PointerType RightPointerType;
+ const StrongPtr & sp = reinterpret_cast< const StrongPtr & >( rhs );
+ PointerType p = sp.GetPointer();
+ const RightPointerType rp = reinterpret_cast< const RightPointerType >( p );
+ p = dynamic_cast< const PointerType >( rp );
+ const bool isNull = ( NULL == p );
+ StrongPtr temp( rhs, isNull, DynamicCastHelper() );
+ Swap( temp );
+ return *this;
+ }
+
+ /// Dynamically-casts parameter pointer to the type specified by this SmartPtr type.
+ template
+ <
+ typename T1,
+ bool S1,
+ class OP1,
+ class CP1,
+ template < class > class KP1,
+ template < class > class RP1,
+ template < class > class DP1,
+ template < class > class CNP1
+ >
+ StrongPtr & DynamicCastFrom( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
+ {
+ typedef typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::PointerType RightPointerType;
+ StrongPtr & sp = reinterpret_cast< StrongPtr & >( rhs );
+ PointerType p = sp.GetPointer();
+ RightPointerType rp = reinterpret_cast< RightPointerType >( p );
+ p = dynamic_cast< PointerType >( rp );
+ const bool isNull = ( NULL == p );
+ StrongPtr temp( rhs, isNull, DynamicCastHelper() );
+ Swap( temp );
+ return *this;
+ }
+
#ifdef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
// old non standard in class definition of friends
@@ -1663,35 +1778,4 @@
namespace std
{
////////////////////////////////////////////////////////////////////////////////
- /// specialization of std::less for StrongPtr
- /// \ingroup SmartPointerGroup
- ////////////////////////////////////////////////////////////////////////////////
- template
- <
- typename T,
- bool S,
- class OP,
- class CP,
- template < class > class KP,
- template < class > class RP,
- template < class > class DP,
- template < class > class CNP
- >
- struct less< Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > >
- : public binary_function<
- Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >,
- Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >, bool >
- {
- bool operator () (
- const Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs,
- const Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs ) const
- {
- return ( lhs < rhs );
- }
- };
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-#endif // end file guardian
-
+ /// specialization of std::less for StroeTracker@Private@Loki@@@std@@@std@@QBEXABV123@@Z |