diff --git a/include/loki/SmartPtr.h b/include/loki/SmartPtr.h index 7295d18..c2cfdf0 100644 --- a/include/loki/SmartPtr.h +++ b/include/loki/SmartPtr.h @@ -45,6 +45,12 @@ #include #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& sp, typename SP1::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::StoredType p) { SmartPtr(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 // diff --git a/include/loki/StrongPtr.h b/include/loki/StrongPtr.h index 31b5595..047ee4b 100644 --- a/include/loki/StrongPtr.h +++ b/include/loki/StrongPtr.h @@ -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::OnReleaseAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) ) + { + return false; + } + p = sp.GetPointer(); + sp.OP::SetPointer( sp.DP::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::OnResetAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) ) + { + return false; + } + sp.DP::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.