Bugs item #1570582, was opened at 2006-10-04 12:13
Message generated for change (Comment added) made by syntheticpp
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=396644&aid=1570582&group_id=29557
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: None
Status: Open
Resolution: None
Priority: 8
Submitted By: Nobody/Anonymous (nobody)
Assigned to: Peter Kuemmel (syntheticpp)
Summary: Loki won't compile on GCC4.1 because of injected friends.
Initial Comment:
Loki uses injected friends which won't work since GCC 4.1:
===========================================
=================
struct foo
{
friend void bar ()
{
}
};
int main ()
{
bar ();
}
===========================================
=================
===========================================
=================
Testing with g++-2.95 version 2.95.4
$ g++-2.95 -c friend.cc
Compilation finished, g++-2.95 returned 0
===========================================
=================
Testing with g++-3.3 version g++-3.3 (GCC) 3.3.6 (Debian
1:3.3.6-13)
$ g++-3.3 -c friend.cc
Compilation finished, g++-3.3 returned 0
===========================================
=================
Testing with g++-3.4 version g++-3.4 (GCC) 3.4.6 (Debian 3.4.6-4)
$ g++-3.4 -c friend.cc
Compilation finished, g++-3.4 returned 0
===========================================
=================
Testing with g++-4.0 version g++-4.0 (GCC) 4.0.4 20060507
(prerelease) (Debian 4.0.3-3)
$ g++-4.0 -c friend.cc
Compilation finished, g++-4.0 returned 0
===========================================
=================
Testing with g++-4.1 version g++-4.1 (GCC) 4.1.2 20060901
(prerelease) (Debian 4.1.1-13)
$ g++-4.1 -c friend.cc
friend.cc: In function 'int main()':
friend.cc:10: error: 'bar' was not declared in this scope
Compilation finished, g++-4.1 returned 1
===========================================
=================
See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28597
----------------------------------------------------------------------
>Comment By: Peter Kuemmel (syntheticpp)
Date: 2006-10-19 16:05
Message:
Logged In: YES
user_id=1159765
All your patches are already in svn (we've migrated to svn)
now (with small corrections).
But despite of the missing forward declarations I get
no errors when compiling Loki, maybe the friend functions
are not used by the loki code.
An other thing is that I could compile tests/SmartPtr
with gcc 4.2 and the old injected friend code without
errors, which I don't understand, because the old code
should not compile without the -ffriend-injection option.
I think we could postpone the forward declaration of
the smart pointer friend functions until gcc could
handle it, currently gcc is to buggy on this issue.
Could you test the svn version of Loki with your
code and gcc 4.1?
Peter
----------------------------------------------------------------------
Comment By: Nobody/Anonymous (nobody)
Date: 2006-10-19 14:22
Message:
Logged In: NO
Hum yeah this FAQ entry is very useful and makes it clear
as to how these tricky things must be written. Could you
post the final diff/patch that will be applied to Loki
please?
If you haven't written it already, I can write it (and post
it) for you.
Regards,
Benoit Sigoure.
----------------------------------------------------------------------
Comment By: Peter Kuemmel (syntheticpp)
Date: 2006-10-18 21:18
Message:
Logged In: YES
user_id=1159765
See also the FAQ about friends
http://gcc.gnu.org/faq.html#friend
----------------------------------------------------------------------
Comment By: Peter Kuemmel (syntheticpp)
Date: 2006-10-17 12:26
Message:
Logged In: YES
user_id=1159765
It's a compiler bug (msvc and all gcc versions,
maybe 4.2 has fixed it):
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29486
- test code added
- workaround added to enable the old in-class-definitions
- GCC 4.1 maybe works with -ffriend-injection
(http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28597)
----------------------------------------------------------------------
Comment By: Peter Kuemmel (syntheticpp)
Date: 2006-10-16 18:55
Message:
Logged In: YES
user_id=1159765
I've tried also to patch StrongPtr, but without success.
All compilers (msvc, gcc 3.4, 4.2) couldn't resolve a
ambiguity of ReleaseAll (after removing the wrong
"typename U" template parameter).
Seems this hits a compiler limit; maybe because of
an incomplete std implementation.
(Partial Ordering of Function Templates?
at least msvc doesn't suppot it)
----------------------------------------------------------------------
Comment By: Peter Kuemmel (syntheticpp)
Date: 2006-10-11 12:58
Message:
Logged In: YES
user_id=1159765
Some moments before your post I've checked in
an additional test. (more or less a copy paste
of the gcc bug report) :)
> [... btw it's a bit annoying to compile
> things in testwhen just making all, this
> should be done during make check only]
This is not by accidient, by also building
the tests we get more builds and thus (hopefully)
more bug reports.
----------------------------------------------------------------------
Comment By: Nobody/Anonymous (nobody)
Date: 2006-10-11 12:35
Message:
Logged In: NO
Alright, let's get it to fail:
$ wget http://belnet.dl.sourceforge.net/sourceforge/loki-
lib/loki-0.1.5.tar.gz
$ tar xfz loki-0.1.5.tar.gz
$ cd loki-0.1.5 && make
[... btw it's a bit annoying to compile things in test/
when just making all, this should be done during make check
only]
make[2]: Entering directory `/tmp/loki/loki-0.1.5/test/
SmartPtr'
g++ -Wall -Wold-style-cast -Wundef -Wsign-compare -
Wconversion -Wpointer-arith -pedantic -g -O2 -I../../
include -DNDEBUG -c -o main.o main.cpp
main.cpp:50:2: warning: #warning is a GCC extension
main.cpp:50:2: warning: #warning The warnings are by
design: Check if SmartPtr can be used with a forward-
reference.
../../include/loki/SmartPtr.h: In member function 'void
Loki::DefaultSPStorage<T>::Destroy() [with T = Thingy]':
../../include/loki/SmartPtr.h:1064: instantiated from
'Loki::SmartPtr<T, OwnershipPolicy, ConversionPolicy,
CheckingPolicy, StoragePolicy,
ConstnessPolicy>::~SmartPtr() [with T = Thingy,
OwnershipPolicy = Loki::RefCounted, ConversionPolicy =
Loki::DisallowConversion, CheckingPolicy =
Loki::AssertCheck, StoragePolicy = Loki::DefaultSPStorage,
ConstnessPolicy = Loki::PropagateConst]'
main.cpp:985: instantiated from here
../../include/loki/SmartPtr.h:169: warning: possible
problem detected in invocation of delete operator:
../../include/loki/SmartPtr.h:169: warning: invalid use of
undefined type 'struct Thingy'
main.cpp:47: warning: forward declaration of 'struct Thingy'
../../include/loki/SmartPtr.h:169: note: neither the
destructor nor the class-specific operator delete will be
called, even if they are declared when the class is defined.
[...]
$ vim test.cc
[...]
$ cat -n test.cc
1 /*
2 ** test.cc for Project in /tmp/loki/loki-0.1.5
3 **
4 ** Made by SIGOURE Benoit
5 ** Mail <sigoure.benoit@...>
6 **
7 ** Started on Wed 11 Oct 2006 12:30:53 PM CEST
SIGOURE Benoit
8 ** Last update Wed 11 Oct 2006 12:32:44 PM CEST
SIGOURE Benoit
9 */
10
11 #include "SmartPtr.h"
12
13 struct Foo
14 {
15 void AddRef ()
16 {
17 }
18
19 void Release ()
20 {
21 }
22 };
23
24 int main ()
25 {
26 // COMRefCounted has the advantage to only use
headers.
27 Loki::SmartPtr<Foo, Loki::COMRefCounted> sp;
28 Foo* p = Loki::GetImpl (sp);
29 }
$ ~/work/cxx/test_cxx.sh -c test.cc -I./include/
loki
List of C++ compilers to test: g++-2.95 g++-3.3 g++-3.4 g++-
4.0 g++-4.1
Testing with g++-2.95 version 2.95.4
$ g++-2.95 -c test.cc -I./include/loki
In file included from include/loki/SmallObj.h:24,
from include/loki/SmartPtr.h:33,
from test.cc:11:
include/loki/Singleton.h: In function `static void
Loki::FollowIntoDeath::With<Lifetime>::AsMasterLifetime<Master>::ScheduleDestruction(Master
*, void (*)())':
include/loki/Singleton.h:656: `Followers' is not a template
include/loki/Singleton.h:663: `Followers' is not a template
include/loki/Singleton.h:663: ANSI C++ forbids declaration
`' with no type
include/loki/Singleton.h:663: `Followers' is not a template
include/loki/Singleton.h: In function `static void
Loki::FollowIntoDeath::AfterMaster<Master>::IsDestroyed<F>::ScheduleDestruction(F
*, void (*)())':
include/loki/Singleton.h:686: `Followers' is not a template
test.cc: In function `int main()':
test.cc:28: `GetImpl' undeclared in namespace `Loki'
Compilation finished, g++-2.95 returned 1
Testing with g++-3.3 version g++-3.3 (GCC) 3.3.6 (Debian
1:3.3.6-13)
$ g++-3.3 -c test.cc -I./include/loki
Compilation finished, g++-3.3 returned 0
Testing with g++-3.4 version g++-3.4 (GCC) 3.4.6 (Debian
3.4.6-4)
$ g++-3.4 -c test.cc -I./include/loki
Compilation finished, g++-3.4 returned 0
Testing with g++-4.0 version g++-4.0 (GCC) 4.0.4 20060507
(prerelease) (Debian 4.0.3-3)
$ g++-4.0 -c test.cc -I./include/loki
Compilation finished, g++-4.0 returned 0
Testing with g++-4.1 version g++-4.1 (GCC) 4.1.2 20060901
(prerelease) (Debian 4.1.1-13)
$ g++-4.1 -c test.cc -I./include/loki
test.cc: In function 'int main()':
test.cc:28: error: 'GetImpl' is not a member of 'Loki'
Compilation finished, g++-4.1 returned 1
----------------------------------------------------------------------
Comment By: Peter Kuemmel (syntheticpp)
Date: 2006-10-10 23:31
Message:
Logged In: YES
user_id=1159765
I've tested the Loki examples with 4.1.0 and
4.2.0 and could not reproduce the error.
So, do you see the problem while compiling Loki,
or when you compile your own code?
----------------------------------------------------------------------
Comment By: Nobody/Anonymous (nobody)
Date: 2006-10-06 14:19
Message:
Logged In: NO
AFAIK I did not let any "friend" keyword at _definition_.
By the way, I'm sorry for the bad quality of the copy/paste
on sourceforge (I've lost my password and email address and
can't recover my SourceForge account ATM).
The patch is available at https://www.tsunanet.net/~tsuna/
loki-friends.patch
----------------------------------------------------------------------
Comment By: Peter Kuemmel (syntheticpp)
Date: 2006-10-05 21:14
Message:
Logged In: YES
user_id=1159765
Thanks, the support of GCC is a must.
Your patch looks good, but isn't "friend"
at the definition superfluously?
----------------------------------------------------------------------
Comment By: Nobody/Anonymous (nobody)
Date: 2006-10-04 17:48
Message:
Logged In: NO
Here is a proposal patch. I only tested the SmartPtr stuff, not the rest. Better
test it before committing in the trunk :)
Index: ChangeLog
===============================================
====================
--- ChangeLog (revision 29)
+++ ChangeLog (revision 30)
@@ -1,5 +1,21 @@
2006-10-04 SIGOURE Benoit <sigoure.benoit@...>
+ Fix Loki.
+ Loki was using injected friends which is not standard. GCC 4.1 thus
+ reports an error. Friends are now declared in the class and defined
+ outside the class (actually, after the class). The bug was reported
+ to Loki at
+ http://sf.net/tracker/?
func=detail&aid=1570582&group_id=29557&atid=396644
+ and this patch was submitted to Loki's developers.
+ See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28597)
+
+ * loki/include/loki/AssocVector.h,
+ * loki/include/loki/StrongPtr.h,
+ * loki/include/loki/SmartPtr.h,
+ * loki/include/loki/AbstractFactory.h: Fix friends.
+
+2006-10-04 SIGOURE Benoit <sigoure.benoit@...>
+
Escape output for XML.
* behavior-graphs/tests/simple.cc: Test the escape.
Index: loki/include/loki/AssocVector.h
===============================================
====================
--- loki/include/loki/AssocVector.h (revision 29)
+++ loki/include/loki/AssocVector.h (revision 30)
@@ -74,6 +74,7 @@
// * iterators are random
///////////////////////////////////////////////////////////////////////
/////////
+
template
<
class K,
@@ -288,33 +289,64 @@
const MyCompare& me = *this;
return std::equal_range(begin(), end(), k, me);
}
-
- friend bool operator==(const AssocVector& lhs, const AssocVector&
rhs)
- {
- const Base& me = lhs;
- return me == rhs;
- }
+ template <class K, class V, class C, class A>
+ friend bool operator==(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs);
+
bool operator<(const AssocVector& rhs) const
{
const Base& me = *this;
const Base& yo = rhs;
return me < yo;
- }
+ }
- friend bool operator!=(const AssocVector& lhs, const AssocVector&
rhs)
- { return !(lhs == rhs); }
+ template <class K, class V, class C, class A>
+ friend bool operator!=(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs);
- friend bool operator>(const AssocVector& lhs, const AssocVector& rhs)
- { return rhs < lhs; }
+ template <class K, class V, class C, class A>
+ friend bool operator>(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs);
- friend bool operator>=(const AssocVector& lhs, const AssocVector&
rhs)
- { return !(lhs < rhs); }
+ template <class K, class V, class C, class A>
+ friend bool operator>=(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs);
- friend bool operator<=(const AssocVector& lhs, const AssocVector&
rhs)
- { return !(rhs < lhs); }
+ template <class K, class V, class C, class A>
+ friend bool operator<=(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs);
};
+ template <class K, class V, class C, class A>
+ inline bool operator==(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs)
+ {
+ const std::vector<std::pair<K, V>, A>& me = lhs;
+ return me == rhs;
+ }
+
+ template <class K, class V, class C, class A>
+ inline bool operator!=(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs)
+ { return !(lhs == rhs); }
+
+ template <class K, class V, class C, class A>
+ inline bool operator>(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs)
+ { return rhs < lhs; }
+
+ template <class K, class V, class C, class A>
+ inline bool operator>=(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs)
+ { return !(lhs < rhs); }
+
+ template <class K, class V, class C, class A>
+ inline bool operator<=(const AssocVector<K, V, C, A>& lhs,
+ const AssocVector<K, V, C, A>& rhs)
+ { return !(rhs < lhs); }
+
+
// specialized algorithms:
template <class K, class V, class C, class A>
void swap(AssocVector<K, V, C, A>& lhs, AssocVector<K, V, C, A>& rhs)
Index: loki/include/loki/StrongPtr.h
===============================================
====================
--- loki/include/loki/StrongPtr.h (revision 29)
+++ loki/include/loki/StrongPtr.h (revision 30)
@@ -751,6 +751,7 @@
/// \param ConstnessPolicy default = LOKI_DEFAULT_CONSTNESS
///////////////////////////////////////////////////////////////////////
/////////
+
template
<
typename T,
@@ -935,33 +936,33 @@
}
}
- friend bool ReleaseAll( StrongPtr & sp,
- typename StrongPtr::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 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 );
- friend bool ResetAll( StrongPtr & sp,
- typename StrongPtr::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;
- }
+ 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 );
/** Merges ownership of two StrongPtr's that point to same shared object
but are not copointers. Requires Merge function in OwnershipPolicy.
@@ -1191,7 +1192,7 @@
typedef typename Select< CP::allow, PointerType, Insipid >::Result
AutomaticConversionResult;
-public:
+public:
operator AutomaticConversionResult() const
{
return GetPointer();
@@ -1199,6 +1200,58 @@
};
+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;
+}
+
//
-----------------------------------------------------------------
-----------
// free comparison operators for class template StrongPtr
Index: loki/include/loki/SmartPtr.h
===============================================
====================
--- loki/include/loki/SmartPtr.h (revision 29)
+++ loki/include/loki/SmartPtr.h (revision 30)
@@ -55,6 +55,7 @@
/// to T's destructor followed by call to free.
///////////////////////////////////////////////////////////////////////
/////////
+
template <class T>
class HeapStorage
{
@@ -85,15 +86,15 @@
{ std::swap(pointee_, rhs.pointee_); }
// Accessors
- friend inline PointerType GetImpl(const HeapStorage& sp)
- { return sp.pointee_; }
-
- friend inline const StoredType& GetImplRef(const HeapStorage& sp)
- { return sp.pointee_; }
+ template <class F>
+ friend typename HeapStorage<F>::PointerType GetImpl(const
HeapStorage<F>& sp);
- friend inline StoredType& GetImplRef(HeapStorage& sp)
- { return sp.pointee_; }
+ template <class F>
+ friend const typename HeapStorage<F>::StoredType& GetImplRef
(const HeapStorage<F>& sp);
+ template <class F>
+ friend typename HeapStorage<F>::StoredType& GetImplRef
(HeapStorage<F>& sp);
+
protected:
// Destroys the data stored
// (Destruction might be taken over by the OwnershipPolicy)
@@ -115,6 +116,19 @@
StoredType pointee_;
};
+ template <class T>
+ inline typename HeapStorage<T>::PointerType GetImpl(const
HeapStorage<T>& sp)
+ { return sp.pointee_; }
+
+ template <class T>
+ inline const typename HeapStorage<T>::StoredType& GetImplRef(const
HeapStorage<T>& sp)
+ { return sp.pointee_; }
+
+ template <class T>
+ inline typename HeapStorage<T>::StoredType& GetImplRef
(HeapStorage<T>& sp)
+ { return sp.pointee_; }
+
+
///////////////////////////////////////////////////////////////////////
/////////
/// \class DefaultSPStorage
///
@@ -122,6 +136,7 @@
/// Implementation of the StoragePolicy used by SmartPtr
///////////////////////////////////////////////////////////////////////
/////////
+
template <class T>
class DefaultSPStorage
{
@@ -152,15 +167,15 @@
{ std::swap(pointee_, rhs.pointee_); }
// Accessors
- friend inline PointerType GetImpl(const DefaultSPStorage& sp)
- { return sp.pointee_; }
-
- friend inline const StoredType& GetImplRef(const DefaultSPStorage&
sp)
- { return sp.pointee_; }
+ template <class F>
+ friend typename DefaultSPStorage<F>::PointerType GetImpl(const
DefaultSPStorage<F>& sp);
- friend inline StoredType& GetImplRef(DefaultSPStorage& sp)
- { return sp.pointee_; }
+ template <class F>
+ friend const typename DefaultSPStorage<F>::StoredType& GetImplRef
(const DefaultSPStorage<F>& sp);
+ template <class F>
+ friend typename DefaultSPStorage<F>::StoredType& GetImplRef
(DefaultSPStorage<F>& sp);
+
protected:
// Destroys the data stored
// (Destruction might be taken over by the OwnershipPolicy)
@@ -178,6 +193,18 @@
StoredType pointee_;
};
+ template <class T>
+ inline typename DefaultSPStorage<T>::PointerType GetImpl(const
DefaultSPStorage<T>& sp)
+ { return sp.pointee_; }
+
+ template <class T>
+ inline const typename DefaultSPStorage<T>::StoredType& GetImplRef
(const DefaultSPStorage<T>& sp)
+ { return sp.pointee_; }
+
+ template <class T>
+ inline typename DefaultSPStorage<T>::StoredType& GetImplRef
(DefaultSPStorage<T>& sp)
+ { return sp.pointee_; }
+
///////////////////////////////////////////////////////////////////////
/////////
/// \class ArrayStorage
@@ -186,6 +213,7 @@
/// Implementation of the ArrayStorage used by SmartPtr
///////////////////////////////////////////////////////////////////////
/////////
+
template <class T>
class ArrayStorage
{
@@ -216,15 +244,15 @@
{ std::swap(pointee_, rhs.pointee_); }
// Accessors
- friend inline PointerType GetImpl(const ArrayStorage& sp)
- { return sp.pointee_; }
-
- friend inline const StoredType& GetImplRef(const ArrayStorage& sp)
- { return sp.pointee_; }
+ template <class F>
+ friend typename ArrayStorage<F>::PointerType GetImpl(const
ArrayStorage<F>& sp);
- friend inline StoredType& GetImplRef(ArrayStorage& sp)
- { return sp.pointee_; }
+ template <class F>
+ friend const typename ArrayStorage<F>::StoredType& GetImplRef
(const ArrayStorage<F>& sp);
+ template <class F>
+ friend typename ArrayStorage<F>::StoredType& GetImplRef
(ArrayStorage<F>& sp);
+
protected:
// Destroys the data stored
// (Destruction might be taken over by the OwnershipPolicy)
@@ -240,7 +268,19 @@
StoredType pointee_;
};
+ template <class T>
+ inline typename ArrayStorage<T>::PointerType GetImpl(const
ArrayStorage<T>& sp)
+ { return sp.pointee_; }
+ template <class T>
+ inline const typename ArrayStorage<T>::StoredType& GetImplRef(const
ArrayStorage<T>& sp)
+ { return sp.pointee_; }
+
+ template <class T>
+ inline typename ArrayStorage<T>::StoredType& GetImplRef
(ArrayStorage<T>& sp)
+ { return sp.pointee_; }
+
+
///////////////////////////////////////////////////////////////////////
/////////
/// \class RefCounted
///
@@ -1064,15 +1104,6 @@
SP::Destroy();
}
}
-
- 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); }
template
<
@@ -1083,6 +1114,32 @@
template <class> class SP1,
template <class> class CNP1
>
+ friend void Release(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1>& sp,
+ typename SP1<T>::StoredType& p);
+
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
+ friend void Reset(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1>& sp,
+ typename SP1<T>::StoredType p);
+
+
+
+ template
+ <
+ typename T1,
+ template <class> class OP1,
+ class CP1,
+ template <class> class KP1,
+ template <class> class SP1,
+ template <class> class CNP1
+ >
bool Merge( SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
{
if ( GetImpl( *this ) != GetImpl( rhs ) )
@@ -1241,6 +1298,37 @@
{ return GetImpl(*this); }
};
+ template
+ <
+ typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP1,
+ typename U
+ >
+ inline void Release(SmartPtr<T, OP, CP, KP, SP, CNP1>& sp,
+ typename SP<T>::StoredType& p)
+ {
+ p = GetImplRef(sp);
+ GetImplRef(sp) = SP<T>::Default();
+ }
+
+ template
+ <
+ typename T,
+ template <class> class OP,
+ class CP,
+ template <class> class KP,
+ template <class> class SP,
+ template <class> class CNP1,
+ typename U
+ >
+ inline void Reset(SmartPtr<T, OP, CP, KP, SP, CNP1>& sp,
+ typename SP<T>::StoredType p)
+ { SmartPtr<T, OP, CP, KP, SP, CNP1>(p).Swap(sp); }
+
///////////////////////////////////////////////////////////////////////
/////////
// free comparison operators for class template SmartPtr
///////////////////////////////////////////////////////////////////////
/////////
Index: loki/include/loki/AbstractFactory.h
===============================================
====================
--- loki/include/loki/AbstractFactory.h (revision 29)
+++ loki/include/loki/AbstractFactory.h (revision 30)
@@ -110,15 +110,15 @@
PrototypeFactoryUnit(AbstractProduct* p = 0)
: pPrototype_(p)
{}
-
- friend void DoGetPrototype(const PrototypeFactoryUnit& me,
- AbstractProduct*& pPrototype)
- { pPrototype = me.pPrototype_; }
-
- friend void DoSetPrototype(PrototypeFactoryUnit& me,
- AbstractProduct* pObj)
- { me.pPrototype_ = pObj; }
-
+
+ template <class CP, class B>
+ friend void DoGetPrototype(const PrototypeFactoryUnit<CP, B>& me,
+ typename Base::ProductList::Head*& pPrototype);
+
+ template <class CP, class B>
+ friend void DoSetPrototype(PrototypeFactoryUnit<CP, B>& me,
+ typename Base::ProductList::Head* pObj);
+
template <class U>
void GetPrototype(U*& p)
{ return DoGetPrototype(*this, p); }
@@ -137,6 +137,16 @@
AbstractProduct* pPrototype_;
};
+ template <class CP, class B>
+ inline void DoGetPrototype(const PrototypeFactoryUnit<CP, B>& me,
+ typename Base::ProductList::Head*& pPrototype)
+ { pPrototype = me.pPrototype_; }
+
+ template <class CP, class B>
+ inline void DoSetPrototype(PrototypeFactoryUnit<CP, B>& me,
+ typename Base::ProductList::Head* pObj)
+ { me.pPrototype_ = pObj; }
+
///////////////////////////////////////////////////////////////////////
/////////
// class template ConcreteFactory
// Implements an AbstractFactory interface
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=396644&aid=1570582&group_id=29557
|