vsmartptr.h

Go to the documentation of this file.
00001 ///
00002 /// \file       vsmartptr.h
00003 ///             Smart pointer that accepts custom 'free' functions.
00004 ///
00005 
00006 /*
00007     Copyright (C) 2006-2012, Net Direct Inc. (http://www.netdirect.ca/)
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018     See the GNU General Public License in the COPYING file at the
00019     root directory of this project for more details.
00020 */
00021 
00022 #ifndef __BARRY_VSMARTPTR_H__
00023 #define __BARRY_VSMARTPTR_H__
00024 
00025 namespace Barry {
00026 
00027 //
00028 // vSmartPtr
00029 //
00030 /// A special smart pointer for variables that have their own
00031 /// special 'free' functions.  Behaves like std::auto_ptr<>
00032 /// in that only one object at a time owns the pointer,
00033 /// and destruction frees it by calling the given FreeFunc.
00034 ///
00035 template <class T, class FT, void (*FreeFunc)(FT *pt)>
00036 class vSmartPtr
00037 {
00038         mutable T *m_pt;
00039 
00040 public:
00041         vSmartPtr() : m_pt(0) {}
00042         vSmartPtr(T *pt) : m_pt(pt) {}
00043         vSmartPtr(const vSmartPtr &sp) : m_pt(sp.m_pt)
00044         {
00045                 sp.m_pt = 0;
00046         }
00047         ~vSmartPtr()
00048         {
00049                 reset();
00050         }
00051 
00052         vSmartPtr& operator=(T *pt)
00053         {
00054                 reset(pt);
00055                 return *this;
00056         }
00057 
00058         vSmartPtr& operator=(const vSmartPtr &sp)
00059         {
00060                 reset(sp.release());
00061                 return *this;
00062         }
00063 
00064         // Some non-standard APIs used by Barry
00065         T* Extract()
00066         {
00067                 return this->release();
00068         }
00069 
00070         T* Get()
00071         {
00072                 return this->get();
00073         }
00074 
00075         // std::auto_ptr<> style API
00076         T* get()
00077         {
00078                 return m_pt;
00079         }
00080 
00081         T* release()
00082         {
00083                 T *rp = m_pt;
00084                 m_pt = 0;
00085                 return rp;
00086         }
00087 
00088         void reset(T *new_obj = 0)
00089         {
00090                 if( m_pt )
00091                         FreeFunc(m_pt);
00092                 m_pt = new_obj;
00093         }
00094 };
00095 
00096 //
00097 // vLateSmartPtr
00098 //
00099 /// Variation of the above smart pointer that allows the user to
00100 /// assign a free function after construction, in the case of
00101 /// dlopen()'d frees.
00102 ///
00103 template <class T, class FreeFuncPtrT>
00104 class vLateSmartPtr
00105 {
00106         mutable T *m_pt;
00107         FreeFuncPtrT m_FreeFuncPtr;
00108 
00109 public:
00110         explicit vLateSmartPtr(FreeFuncPtrT freefunc = 0)
00111                 : m_pt(0)
00112                 , m_FreeFuncPtr(freefunc)
00113         {
00114         }
00115 
00116         vLateSmartPtr(T *pt, FreeFuncPtrT freefunc = 0)
00117                 : m_pt(pt)
00118                 , m_FreeFuncPtr(freefunc)
00119         {
00120         }
00121 
00122         vLateSmartPtr(const vLateSmartPtr &sp)
00123                 : m_pt(sp.m_pt)
00124                 , m_FreeFuncPtr(sp.m_FreeFuncPtr)
00125         {
00126                 sp.m_pt = 0;
00127         }
00128 
00129         ~vLateSmartPtr()
00130         {
00131                 reset();
00132         }
00133 
00134         void SetFreeFunc(FreeFuncPtrT freefunc)
00135         {
00136                 m_FreeFuncPtr = freefunc;
00137         }
00138 
00139         vLateSmartPtr& operator=(T *pt)
00140         {
00141                 reset(pt);
00142                 return *this;
00143         }
00144 
00145         vLateSmartPtr& operator=(const vLateSmartPtr &sp)
00146         {
00147                 reset(sp.release());
00148                 m_FreeFuncPtr = sp.m_FreeFuncPtr;
00149                 return *this;
00150         }
00151 
00152         // Some non-standard APIs used by Barry
00153         T* Extract()
00154         {
00155                 return this->release();
00156         }
00157 
00158         T* Get()
00159         {
00160                 return this->get();
00161         }
00162 
00163         // std::auto_ptr<> style API
00164         T* get()
00165         {
00166                 return m_pt;
00167         }
00168 
00169         T* release()
00170         {
00171                 T *rp = m_pt;
00172                 m_pt = 0;
00173                 return rp;
00174         }
00175 
00176         void reset(T *new_obj = 0)
00177         {
00178                 // don't check for null m_FreeFuncPtr, since
00179                 // that should be an obvious crash and requires fixing
00180                 if( m_pt )
00181                         (*m_FreeFuncPtr)(m_pt);
00182                 m_pt = new_obj;
00183         }
00184 };
00185 
00186 /*
00187 
00188 Example usage:
00189 
00190 typedef vSmartPtr<b_VFormatAttribute, b_VFormatAttribute, &b_vformat_attribute_free> vAttrPtr;
00191 typedef vSmartPtr<b_VFormatParam, b_VFormatParam, &b_vformat_attribute_param_free> vParamPtr;
00192 typedef vSmartPtr<char, void, &g_free> gStringPtr;
00193 
00194 */
00195 
00196 } // namespace Barry
00197 
00198 #endif
00199