workaround for broken msvc/gcc: template friends with template template parameters

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@732 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
syntheticpp 2006-10-17 10:06:58 +00:00
parent 56c73cd3bc
commit 812423e188
2 changed files with 126 additions and 1 deletions

View file

@ -45,6 +45,12 @@
#include <stdint.h>
#endif
#if defined(_MSC_VER) || defined(__GNUC__)
// GCC>=4.1 must use -ffriend-injection due to a bug in GCC
#define LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
#endif
namespace Loki
{
@ -1106,6 +1112,20 @@ namespace Loki
}
}
#ifdef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
// old non standard in class definition of friends
friend inline void Release(SmartPtr& sp, typename SP::StoredType& p)
{
p = GetImplRef(sp);
GetImplRef(sp) = SP::Default();
}
friend inline void Reset(SmartPtr& sp, typename SP::StoredType p)
{ SmartPtr(p).Swap(sp); }
#else
template
<
typename T1,
@ -1129,7 +1149,7 @@ namespace Loki
>
friend void Reset(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1>& sp,
typename SP1<T1>::StoredType p);
#endif
template
@ -1304,6 +1324,8 @@ namespace Loki
// friends
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
template
<
typename T,
@ -1333,6 +1355,8 @@ namespace Loki
typename SP<T>::StoredType p)
{ SmartPtr<T, OP, CP, KP, SP, CNP>(p).Swap(sp); }
#endif
////////////////////////////////////////////////////////////////////////////////
// free comparison operators for class template SmartPtr
////////////////////////////////////////////////////////////////////////////////
@ -1617,6 +1641,9 @@ namespace std
// $Log$
// Revision 1.37 2006/10/17 10:06:58 syntheticpp
// workaround for broken msvc/gcc: template friends with template template parameters
//
// Revision 1.36 2006/10/17 09:14:27 syntheticpp
// fix wrong friend declaration
//

View file

@ -955,6 +955,9 @@ public:
}
}
#ifdef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
// old non standard in class definition of friends
friend bool ReleaseAll( StrongPtr & sp,
typename StrongPtr::StoredType & p )
{
@ -983,6 +986,40 @@ public:
return true;
}
#else
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
>
friend bool ReleaseAll( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & sp,
typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::StoredType & p );
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
>
friend bool ResetAll( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & sp,
typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::StoredType p );
#endif
/** Merges ownership of two StrongPtr's that point to same shared object
but are not copointers. Requires Merge function in OwnershipPolicy.
\return True for success, false if not pointer to same object.
@ -1221,6 +1258,64 @@ public:
// ----------------------------------------------------------------------------
// friend functions
#ifndef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
template
<
typename U,
typename T,
bool S,
class OP,
class CP,
template < class > class KP,
template < class > class RP,
template < class > class DP,
template < class > class CNP
>
bool ReleaseAll( StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & sp,
typename StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >::StoredType & p )
{
if ( !sp.RP<T>::OnReleaseAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) )
{
return false;
}
p = sp.GetPointer();
sp.OP::SetPointer( sp.DP<T>::Default() );
return true;
}
template
<
typename U,
typename T,
bool S,
class OP,
class CP,
template < class > class KP,
template < class > class RP,
template < class > class DP,
template < class > class CNP
>
bool ResetAll( StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & sp,
typename StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >::StoredType p )
{
if ( sp.OP::GetPointer() == p )
{
return true;
}
if ( !sp.RP<T>::OnResetAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) )
{
return false;
}
sp.DP<T>::Delete( sp.GetPointer() );
sp.OP::SetPointer( p );
return true;
}
#endif
// free comparison operators for class template StrongPtr
/// operator== for lhs = StrongPtr, rhs = raw pointer
@ -1501,6 +1596,9 @@ namespace std
#endif // end file guardian
// $Log$
// Revision 1.9 2006/10/17 10:06:58 syntheticpp
// workaround for broken msvc/gcc: template friends with template template parameters
//
// Revision 1.8 2006/10/14 00:01:05 rich_sposato
// Added #ifdef sections around policy and implementation classes that only
// work properly in multi-threaded model.