Index: ChangeLog
===================================================================
--- ChangeLog	(revision 29)
+++ ChangeLog	(revision 30)
@@ -1,5 +1,21 @@
 2006-10-04  SIGOURE Benoit  <sigoure.benoit@lrde.epita.fr>
 
+	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@lrde.epita.fr>
+
 	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
