| Home | nevrax.com |
|
smart_ptr_inline.hGo 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 ©)
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 ©)
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
|
||||||||||||||||||||||||