• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

Ptr.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /*************************** -*- Mod: C++ -*- ******************************
00025 
00026    Atmic and non-atomic smart pointers.
00027 
00028    Note: it would have been nice to have one 'Ptr' class, but the
00029    templating system on some compilers is so broken that it cannot
00030    correctly compile Ptr without downcasting the m_ptr object to
00031    a RefCountObj.
00032 
00033 
00034  ****************************************************************************/
00035 #if !defined (_Ptr_h_)
00036 #define _Ptr_h_
00037 
00038 #include "ink_atomic.h"
00039 
00040 ////////////////////////////////////////////////////////////////////////
00041 //
00042 // class NonAtomicRefCountObj
00043 // prototypical class for reference counting
00044 //
00045 ////////////////////////////////////////////////////////////////////////
00046 class NonAtomicRefCountObj
00047 {
00048 public:
00049   NonAtomicRefCountObj():m_refcount(0)
00050   {
00051     return;
00052   }
00053   NonAtomicRefCountObj(const NonAtomicRefCountObj & s):m_refcount(0)
00054   {
00055     (void) s;
00056     return;
00057   }
00058   virtual ~ NonAtomicRefCountObj() {
00059     return;
00060   }
00061   NonAtomicRefCountObj & operator =(const NonAtomicRefCountObj & s) {
00062     (void) s;
00063     return (*this);
00064   }
00065 
00066   int refcount_inc();
00067   int refcount_dec();
00068   int refcount() const;
00069 
00070   virtual void free()
00071   {
00072     delete this;
00073   }
00074 
00075   volatile int m_refcount;
00076 };
00077 
00078 inline int
00079 NonAtomicRefCountObj::refcount_inc()
00080 {
00081   return ++m_refcount;
00082 }
00083 
00084 #define NONATOMIC_REF_COUNT_OBJ_REFCOUNT_INC(_x) (_x)->refcount_inc()
00085 
00086 inline int
00087 NonAtomicRefCountObj::refcount_dec()
00088 {
00089   return --m_refcount;
00090 }
00091 
00092 #define NONATOMIC_REF_COUNT_OBJ_REFCOUNT_DEC(_x) (_x)->refcount_dec()
00093 
00094 inline int
00095 NonAtomicRefCountObj::refcount() const
00096 {
00097   return m_refcount;
00098 }
00099 
00100 
00101 
00102 ////////////////////////////////////////////////////////////////////////
00103 //
00104 // class NonAtomicPtr
00105 //
00106 ////////////////////////////////////////////////////////////////////////
00107 template<class T> class NonAtomicPtr {
00108 public:
00109   explicit NonAtomicPtr(T * ptr = 0);
00110   NonAtomicPtr(const NonAtomicPtr<T> &);
00111   ~NonAtomicPtr();
00112 
00113   NonAtomicPtr<T> &operator =(const NonAtomicPtr<T> &);
00114   NonAtomicPtr<T> &operator =(T *);
00115 
00116   void clear();
00117 
00118   operator  T *() const
00119   {
00120     return (m_ptr);
00121   }
00122   T *operator ->() const
00123   {
00124     return (m_ptr);
00125   }
00126   T & operator *() const
00127   {
00128     return (*m_ptr);
00129   }
00130 
00131   int operator ==(const T * p)
00132   {
00133     return (m_ptr == p);
00134   }
00135   int operator ==(const NonAtomicPtr<T> &p)
00136   {
00137     return (m_ptr == p.m_ptr);
00138   }
00139   int operator !=(const T * p)
00140   {
00141     return (m_ptr != p);
00142   }
00143   int operator !=(const NonAtomicPtr<T> &p)
00144   {
00145     return (m_ptr != p.m_ptr);
00146   }
00147 
00148   NonAtomicRefCountObj *_ptr()
00149   {
00150     return (NonAtomicRefCountObj *) m_ptr;
00151   }
00152 
00153   T *m_ptr;
00154 };
00155 
00156 template <typename T>
00157 NonAtomicPtr<T> make_nonatomic_ptr(T * p) {
00158   return NonAtomicPtr<T>(p);
00159 }
00160 
00161 ////////////////////////////////////////////////////////////////////////
00162 //
00163 // inline functions definitions
00164 //
00165 ////////////////////////////////////////////////////////////////////////
00166 template<class T> inline NonAtomicPtr<T>::NonAtomicPtr(T * ptr /* = 0 */ )
00167 :
00168 m_ptr(ptr)
00169 {
00170   if (m_ptr)
00171     _ptr()->refcount_inc();
00172   return;
00173 }
00174 
00175 template<class T> inline NonAtomicPtr<T>::NonAtomicPtr(const NonAtomicPtr<T> &src)
00176 :
00177 m_ptr(src.m_ptr)
00178 {
00179   if (m_ptr)
00180     _ptr()->refcount_inc();
00181   return;
00182 }
00183 
00184 template<class T> inline NonAtomicPtr<T>::~NonAtomicPtr()
00185 {
00186   if ((m_ptr) && _ptr()->refcount_dec() == 0) {
00187     _ptr()->free();
00188   }
00189   return;
00190 }
00191 
00192 template<class T> inline NonAtomicPtr<T> &NonAtomicPtr<T>::operator =(T * p)
00193 {
00194   T *temp_ptr = m_ptr;
00195 
00196   if (m_ptr == p)
00197     return (*this);
00198 
00199   m_ptr = p;
00200 
00201   if (m_ptr != 0) {
00202     _ptr()->refcount_inc();
00203   }
00204 
00205   if ((temp_ptr) && ((NonAtomicRefCountObj *) temp_ptr)->refcount_dec() == 0) {
00206     ((NonAtomicRefCountObj *) temp_ptr)->free();
00207   }
00208 
00209   return (*this);
00210 }
00211 template<class T> inline void NonAtomicPtr<T>::clear()
00212 {
00213   if (m_ptr) {
00214     if (!((NonAtomicRefCountObj *) m_ptr)->refcount_dec())
00215       ((NonAtomicRefCountObj *) m_ptr)->free();
00216     m_ptr = NULL;
00217   }
00218 }
00219 template<class T> inline NonAtomicPtr<T> &NonAtomicPtr<T>::operator =(const NonAtomicPtr<T> &src)
00220 {
00221   return (operator =(src.m_ptr));
00222 }
00223 
00224 
00225 ////////////////////////////////////////////////////////////////////
00226 ////////////////////////////////////////////////////////////////////
00227 //////              ATOMIC VERSIONS
00228 ////////////////////////////////////////////////////////////////////
00229 ////////////////////////////////////////////////////////////////////
00230 
00231 struct ForceVFPTToTop
00232 {
00233   virtual ~ ForceVFPTToTop()
00234   {
00235   }
00236 };
00237 
00238 
00239 ////////////////////////////////////////////////////////////////////////
00240 //
00241 // class RefCountObj
00242 // prototypical class for reference counting
00243 //
00244 ////////////////////////////////////////////////////////////////////////
00245 class RefCountObj: public ForceVFPTToTop
00246 {
00247 public:
00248   RefCountObj():m_refcount(0)
00249   {
00250   }
00251   RefCountObj(const RefCountObj & s):m_refcount(0)
00252   {
00253     (void) s;
00254     return;
00255   }
00256   virtual ~ RefCountObj() {
00257   }
00258   RefCountObj & operator =(const RefCountObj & s) {
00259     (void) s;
00260     return (*this);
00261   }
00262 
00263   int refcount_inc();
00264   int refcount_dec();
00265   int refcount() const;
00266 
00267   virtual void free()
00268   {
00269     delete this;
00270   }
00271 
00272   volatile int m_refcount;
00273 };
00274 
00275 // Increment the reference count, returning the new count.
00276 inline int
00277 RefCountObj::refcount_inc()
00278 {
00279   return ink_atomic_increment((int *) &m_refcount, 1) + 1;
00280 }
00281 
00282 #define REF_COUNT_OBJ_REFCOUNT_INC(_x) (_x)->refcount_inc()
00283 
00284 // Decrement the reference count, returning the new count.
00285 inline int
00286 RefCountObj::refcount_dec()
00287 {
00288   return ink_atomic_increment((int *) &m_refcount, -1) - 1;
00289 }
00290 
00291 #define REF_COUNT_OBJ_REFCOUNT_DEC(_x) (_x)->refcount_dec()
00292 
00293 inline int
00294 RefCountObj::refcount() const
00295 {
00296   return m_refcount;
00297 }
00298 
00299 
00300 ////////////////////////////////////////////////////////////////////////
00301 //
00302 // class Ptr
00303 //
00304 ////////////////////////////////////////////////////////////////////////
00305 template<class T> class Ptr {
00306 public:
00307   explicit Ptr(T * p = 0);
00308   Ptr(const Ptr<T> &);
00309   ~Ptr();
00310 
00311   void clear();
00312   Ptr<T> &operator =(const Ptr<T> &);
00313   Ptr<T> &operator =(T *);
00314 
00315   T * to_ptr() {
00316     if (m_ptr && m_ptr->m_refcount == 1) {
00317       T * ptr = m_ptr;
00318       m_ptr = 0;
00319       ptr->m_refcount = 0;
00320       return ptr;
00321     }
00322     return 0;
00323   }
00324   operator  T *() const
00325   {
00326     return (m_ptr);
00327   }
00328   T *operator ->() const
00329   {
00330     return (m_ptr);
00331   }
00332   T & operator *() const
00333   {
00334     return (*m_ptr);
00335   }
00336 
00337   int operator ==(const T * p)
00338   {
00339     return (m_ptr == p);
00340   }
00341   int operator ==(const Ptr<T> &p)
00342   {
00343     return (m_ptr == p.m_ptr);
00344   }
00345   int operator !=(const T * p)
00346   {
00347     return (m_ptr != p);
00348   }
00349   int operator !=(const Ptr<T> &p)
00350   {
00351     return (m_ptr != p.m_ptr);
00352   }
00353 
00354   RefCountObj *_ptr()
00355   {
00356     return (RefCountObj *) m_ptr;
00357   }
00358 
00359   T *m_ptr;
00360 };
00361 
00362 template <typename T>
00363 Ptr<T> make_ptr(T * p) {
00364   return Ptr<T>(p);
00365 }
00366 
00367 ////////////////////////////////////////////////////////////////////////
00368 //
00369 // inline functions definitions
00370 //
00371 ////////////////////////////////////////////////////////////////////////
00372 template<class T> inline Ptr<T>::Ptr(T * ptr /* = 0 */ )
00373 :
00374 m_ptr(ptr)
00375 {
00376   if (m_ptr)
00377     _ptr()->refcount_inc();
00378   return;
00379 }
00380 
00381 template<class T> inline Ptr<T>::Ptr(const Ptr<T> &src)
00382 :
00383 m_ptr(src.m_ptr)
00384 {
00385   if (m_ptr)
00386     _ptr()->refcount_inc();
00387   return;
00388 }
00389 
00390 template<class T> inline Ptr<T>::~Ptr()
00391 {
00392   if ((m_ptr) && _ptr()->refcount_dec() == 0) {
00393     _ptr()->free();
00394   }
00395   return;
00396 }
00397 
00398 template<class T> inline Ptr<T> &Ptr<T>::operator =(T * p)
00399 {
00400   T *temp_ptr = m_ptr;
00401 
00402   if (m_ptr == p)
00403     return (*this);
00404 
00405   m_ptr = p;
00406 
00407   if (m_ptr != 0) {
00408     _ptr()->refcount_inc();
00409   }
00410 
00411   if ((temp_ptr) && ((RefCountObj *) temp_ptr)->refcount_dec() == 0) {
00412     ((RefCountObj *) temp_ptr)->free();
00413   }
00414 
00415   return (*this);
00416 }
00417 template<class T> inline void Ptr<T>::clear()
00418 {
00419   if (m_ptr) {
00420     if (!((RefCountObj *) m_ptr)->refcount_dec())
00421       ((RefCountObj *) m_ptr)->free();
00422     m_ptr = NULL;
00423   }
00424 }
00425 template<class T> inline Ptr<T> &Ptr<T>::operator =(const Ptr<T> &src)
00426 {
00427   return (operator =(src.m_ptr));
00428 }
00429 
00430 #endif

Generated by  doxygen 1.7.1