# vsmartptr.h

    00001 ///
    00002 /// \file       vsmartptr
    00003 ///             Variable 'free' smart pointer
    00004 ///
    00005
    00006 /*
    00007     Copyright (C) 2006-2011, 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