Smart Pointers

sync_ptr.hpp

00001 // sync_ptr.h 
00002 
00003 #ifndef SYNC_PTR_H_BY_DAVID_MAISONAVE_HEADER_GUARD_
00004 #define SYNC_PTR_H_BY_DAVID_MAISONAVE_HEADER_GUARD_
00005 
00006 #include <memory>
00007 #include "sync_ctrl.h"  //download at http://code.axter.com/sync_ctrl.h
00008 
00051 template<class T, class SYNC_T = sync_ctrl_default, class AX_TYPE = std::allocator<T>, class AX_SYNC_CTRL = std::allocator<SYNC_T> >
00052 class sync_ptr
00053 {
00054 protected:
00055         sync_ptr(T* type, SYNC_T *sync_ctrl_, int* RefCount_)
00056                 :m_type(type), m_sync_ctrl(sync_ctrl_), m_RefCount(RefCount_)
00057         {
00058                 m_sync_ctrl->lock();
00059                 ++(*m_RefCount);
00060                 m_sync_ctrl->unlock();
00061         }
00062 public:
00063         sync_ptr(T* type, SYNC_T *sync_ctrl_ = new SYNC_T)
00064                 :m_type(type), m_sync_ctrl(sync_ctrl_), m_RefCount(new int(1)){}
00065         virtual ~sync_ptr()
00066         {
00067                 m_sync_ctrl->lock();
00068                 if (m_RefCount) --(*m_RefCount);
00069                 if (!m_RefCount || !(*m_RefCount))
00070                 {
00071                         AX_TYPE alloc;
00072                         alloc.destroy(m_type);
00073                         alloc.deallocate(m_type, 1);
00074                         m_type=NULL;
00075                         if (m_RefCount) {delete m_RefCount;m_RefCount=NULL;}
00076                 }
00077                 m_sync_ctrl->unlock();
00078                 if (!m_RefCount)
00079                 {
00080                         AX_SYNC_CTRL alloc;
00081                         alloc.destroy(m_sync_ctrl);
00082                         alloc.deallocate(m_sync_ctrl, 1);
00083                 }
00084         }
00089         class RefLockPtr
00090         {
00091                 struct RefData{
00092                         int m_RefCount;
00093                         T* m_type;
00094                         SYNC_T *m_sync_ctrl;
00095                         bool *m_trylock_stat;
00096                 };
00097                 public:
00098                         friend class sync_ptr<T, SYNC_T, AX_TYPE, AX_SYNC_CTRL>;
00099                         RefLockPtr(const RefLockPtr& Src):m_RefData(Src.m_RefData)
00100                         {
00101                                 ++m_RefData->m_RefCount;
00102                         }
00103                         ~RefLockPtr()
00104                         {
00105                                 --m_RefData->m_RefCount;
00106                                 if (!m_RefData->m_RefCount)
00107                                 {
00108                                         if (!m_RefData->m_trylock_stat || (*m_RefData->m_trylock_stat)) 
00109                                         {
00110                                                 m_RefData->m_sync_ctrl->unlock();
00111                                         }
00112                                         delete m_RefData;
00113                                         m_RefData=NULL;
00114                                 }
00115                         }
00116                         T* operator->() const{return get_ptr();}
00117                         T& operator*() const{return *get_ptr();}
00118                         bool islocked()const{
00119                                 if (!m_RefData->m_trylock_stat || (*m_RefData->m_trylock_stat)) return true;
00120                                 return false;
00121                         }
00122                 protected:
00123                         RefLockPtr(T* type, SYNC_T *sync_ctrl_, bool *trylock_stat = NULL)
00124                                 :m_RefData(new RefData)
00125                         {
00126                                 m_RefData->m_RefCount = 1;
00127                                 m_RefData->m_type = type;
00128                                 m_RefData->m_sync_ctrl = sync_ctrl_;
00129                                 m_RefData->m_trylock_stat = trylock_stat;
00130                                 if(m_RefData->m_trylock_stat)
00131                                 {
00132                                         *m_RefData->m_trylock_stat = m_RefData->m_sync_ctrl->trylock();
00133                                 }
00134                                 else m_RefData->m_sync_ctrl->lock();
00135                         }
00136                         T* get_ptr()const
00137                         {
00138                                 if (!m_RefData->m_trylock_stat || (*m_RefData->m_trylock_stat)) return m_RefData->m_type;
00139                                 return NULL;
00140                         }
00141                         RefLockPtr& operator=(const RefLockPtr&);
00142                         RefData *m_RefData;
00143         };
00144         RefLockPtr operator->(){return RefLockPtr(m_type, m_sync_ctrl);}
00145         RefLockPtr operator*(){return RefLockPtr(m_type, m_sync_ctrl);}
00146         //T& operator*() {return (*RefLockPtr(m_type, m_sync_ctrl));}
00147         RefLockPtr get_locked_obj(bool *trylock_stat = NULL){return RefLockPtr(m_type, m_sync_ctrl, trylock_stat);}
00148         protected:
00149                 sync_ptr& operator=(const sync_ptr&);
00150                 sync_ptr(const sync_ptr& Src);
00151                 bool operator==(const sync_ptr&);
00152                 bool operator!=(const sync_ptr&);
00153                 // Data members
00154                 T* m_type;
00155                 SYNC_T *m_sync_ctrl;
00156                 int *m_RefCount;
00157 };
00158 
00162 template<class T, class SYNC_T = sync_ctrl_default, class AX_TYPE = std::allocator<T>, class AX_SYNC_CTRL = std::allocator<SYNC_T> >
00163 class sync_ref_ptr : public sync_ptr<T, SYNC_T, AX_TYPE, AX_SYNC_CTRL>
00164 {
00165 public:
00166         sync_ref_ptr(const sync_ref_ptr& Src)
00167                 :sync_ptr<T, SYNC_T, AX_TYPE, AX_SYNC_CTRL>(Src.m_type, Src.m_sync_ctrl, Src.m_RefCount){}
00168         sync_ref_ptr(T* type, SYNC_T *sync_ctrl_ = new SYNC_T)
00169                 :sync_ptr<T, SYNC_T, AX_TYPE, AX_SYNC_CTRL>(type, sync_ctrl_){}
00170 private:
00171         sync_ref_ptr& operator=(const sync_ref_ptr&);
00172         bool operator==(const sync_ref_ptr&);
00173         bool operator!=(const sync_ref_ptr&);
00174 };
00175 
00176 #endif 
00177 
00178 

Generated on Wed Mar 29 21:58:59 2006 for Smart Pointers by  doxygen 1.4.6.Axter [Axter-Extended-Version]