# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

smart_ptr_inline.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 
00027 #ifndef NL_SMARTPTR_INLINE_H
00028 #define NL_SMARTPTR_INLINE_H
00029 
00030 namespace       NLMISC
00031 {
00032 
00033 
00034 
00035 // ***************************************************************************
00036 #ifdef NL_OS_WINDOWS
00037 #define SMART_INLINE __forceinline
00038 #else
00039 #define SMART_INLINE inline 
00040 #endif
00041 
00042 
00043 // ***************************************************************************
00044 inline CRefCount::~CRefCount()
00045 {
00046         // This is the destruction of the objet.
00047 
00048         // If a CRefPtr still points on me...
00049         if(!pinfo->IsNullPtrInfo)
00050         {
00051                 // inform them of my destruction.
00052                 pinfo->Ptr= NULL;
00053         }
00054 }
00055 
00056 
00057 // ***************************************************************************
00058 // ***************************************************************************
00059 // CSmartPtr.
00060 // ***************************************************************************
00061 // ***************************************************************************
00062 
00063 
00064 // ***************************************************************************
00065 template<class T>
00066 inline CSmartPtr<T>::~CSmartPtr(void) 
00067 { 
00068         SMART_TRACE("dtor()");
00069 
00070     if(Ptr)
00071         {
00072                 if (--(Ptr->crefs) == 0)
00073                         delete Ptr;
00074                 Ptr=NULL;
00075         }
00076 }
00077 template<class T>    
00078 SMART_INLINE CSmartPtr<T>& CSmartPtr<T>::operator=(T* p)
00079 {
00080         SMART_TRACE("ope=(T*)Start");
00081 
00082         // Implicit manage auto-assignation.
00083     if(p)
00084                 p->crefs++;
00085     if(Ptr)
00086         {
00087                 if (--(Ptr->crefs) == 0)
00088                         delete Ptr;
00089         }
00090         Ptr = p;
00091 
00092         SMART_TRACE("ope=(T*)End");
00093 
00094         return *this;
00095 }
00096 template<class T>    
00097 SMART_INLINE CSmartPtr<T>& CSmartPtr<T>::operator=(const CSmartPtr &p)
00098 {
00099         return operator=(p.Ptr);
00100 }
00101 template<class T>    
00102 SMART_INLINE bool CSmartPtr<T>::operator<(const CSmartPtr &p) const
00103 {
00104         return Ptr<p.Ptr;
00105 }
00106 
00107 
00108 
00109 // ***************************************************************************
00110 // ***************************************************************************
00111 // CRefPtr.
00112 // ***************************************************************************
00113 // ***************************************************************************
00114 
00115 
00116 // ***************************************************************************
00117 template<class T>    
00118 SMART_INLINE void       CRefPtr<T>::unRef() const
00119 {
00120         pinfo->RefCount--;
00121         if(pinfo->RefCount==0)
00122         {
00123                 // In CRefPtr, Never delete the object.
00124 
00125                 // We may be in the case that this==NullPtrInfo, and our NullPtrInfo has done a total round. Test it.
00126                 if(pinfo->IsNullPtrInfo)
00127                 {
00128                         // This should not happens, but I'm not sure :) ...
00129                         // Reset the NullPtrInfo to a middle round.
00130                         pinfo->RefCount= 0x7FFFFFFF;
00131                 }
00132                 else
00133                 {
00134                         // If the CRefPtr still point to a valid object.
00135                         if(pinfo->Ptr)
00136                         {
00137                                 // Inform the Object that no more CRefPtr points on it.
00138                                 ((T*)(pinfo->Ptr))->pinfo= &CRefCount::NullPtrInfo;
00139                         }
00140                         // Then delete the pinfo.
00141                         delete pinfo;
00142                 }
00143 
00144         }
00145 }
00146 
00147 
00148 // ***************************************************************************
00149 // Cons - dest.
00150 template <class T> inline CRefPtr<T>::CRefPtr() 
00151 { 
00152         pinfo= &CRefCount::NullPtrInfo;
00153         Ptr= NULL;
00154 
00155         REF_TRACE("Smart()");
00156 }
00157 template <class T> inline CRefPtr<T>::CRefPtr(T *v)
00158 {
00159         Ptr= v;
00160     if(v)
00161         {
00162                 // If no CRefPtr handles v, create a pinfo ref...
00163                 if(v->pinfo->IsNullPtrInfo)
00164                         v->pinfo=new CRefCount::CPtrInfo(v);
00165                 pinfo=v->pinfo;
00166                 // v is now used by this.
00167                 pinfo->RefCount++;
00168         }
00169         else
00170                 pinfo= &CRefCount::NullPtrInfo;
00171 
00172         REF_TRACE("Smart(T*)");
00173 }
00174 template <class T> inline CRefPtr<T>::CRefPtr(const CRefPtr &copy)
00175 {
00176         pinfo=copy.pinfo;
00177         pinfo->RefCount++;
00178         Ptr= (T*)pinfo->Ptr;
00179 
00180         REF_TRACE("SmartCopy()");
00181 }
00182 template <class T> inline CRefPtr<T>::~CRefPtr(void)
00183 {
00184         REF_TRACE("~Smart()");
00185 
00186         unRef();
00187         pinfo= &CRefCount::NullPtrInfo;
00188         Ptr= NULL;
00189 }
00190 
00191 // ***************************************************************************
00192 // Operators=.
00193 template <class T> CRefPtr<T> &CRefPtr<T>::operator=(T *v) 
00194 {
00195         REF_TRACE("ope=(T*)Start");
00196 
00197 
00198         Ptr= v;
00199         if(v)
00200         {
00201                 // If no CRefPtr handles v, create a pinfo ref...
00202                 if(v->pinfo->IsNullPtrInfo)
00203                         v->pinfo=new CRefCount::CPtrInfo(v);
00204                 // The auto equality test is implicitly done by upcounting first "v", then downcounting "this".
00205                 v->pinfo->RefCount++;
00206                 unRef();
00207                 pinfo= v->pinfo;
00208         }
00209         else
00210         {
00211                 unRef();
00212                 pinfo= &CRefCount::NullPtrInfo;
00213         }
00214 
00215 
00216         REF_TRACE("ope=(T*)End");
00217 
00218         return *this;
00219 }
00220 template <class T> CRefPtr<T> &CRefPtr<T>::operator=(const CRefPtr &copy) 
00221 {
00222         REF_TRACE("ope=(Smart)Start");
00223 
00224         // The auto equality test is implicitly done by upcounting first "copy", then downcounting "this".
00225         copy.pinfo->RefCount++;
00226         unRef();
00227         pinfo=copy.pinfo;
00228         // Must Refresh the ptr.
00229         Ptr= (T*)pinfo->Ptr;
00230 
00231         REF_TRACE("ope=(Smart)End");
00232         return *this;
00233 }
00234 
00235 
00236 // ***************************************************************************
00237 // Operations.
00238 template <class T> void CRefPtr<T>::kill()
00239 {
00240         REF_TRACE("SmartKill");
00241 
00242         T       *ptr= (T*)pinfo->Ptr;
00243 
00244         // First, release the refptr.
00245         unRef();
00246         pinfo= &CRefCount::NullPtrInfo;
00247         Ptr= NULL;
00248 
00249         // Then delete the pointer.
00250         if(ptr)
00251                 delete ptr;
00252 }
00253 
00254 
00255 // ***************************************************************************
00256 // Cast.
00257 template <class T> inline CRefPtr<T>::operator T*()     const 
00258 {
00259         REF_TRACE("SmartCast T*()");
00260 
00261         // Refresh Ptr.
00262         Ptr= (T*)pinfo->Ptr;
00263         return Ptr;
00264 }
00265 
00266 
00267 // ***************************************************************************
00268 // Operators.
00269 template <class T> inline T& CRefPtr<T>::operator*(void)  const
00270 { 
00271         REF_TRACE("Smart *()");
00272         return *Ptr; 
00273 }
00274 template <class T> inline T* CRefPtr<T>::operator->(void) const
00275 { 
00276         REF_TRACE("Smart ->()");
00277         return Ptr;  
00278 }
00279 
00280 
00281 // ***************************************************************************
00282 #undef  SMART_INLINE
00283 
00284 
00285 
00286 } // NLMISC
00287 
00288 
00289 #endif // NL_SMARTPTR_INLINE_H
00290