1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
|
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// copyright : (C) 2008 by Eran Ifrah
// file name : smart_ptr.h
//
// -------------------------------------------------------------------------
// A
// _____ _ _ _ _
// / __ \ | | | | (_) |
// | / \/ ___ __| | ___| | _| |_ ___
// | | / _ \ / _ |/ _ \ | | | __/ _ )
// | \__/\ (_) | (_| | __/ |___| | || __/
// \____/\___/ \__,_|\___\_____/_|\__\___|
//
// F i l e
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#ifndef CODELITE_SMART_PTR_H
#define CODELITE_SMART_PTR_H
#include <stdlib.h>
/**
* A smart pointer class that provides a reference counting and auto delete memory.
*
* This class is similar to std::auto_ptr, with 2 exceptions:
* - This class uses reference counting
* - We dont provide a release() function (because of the reference counting)
* It is recommended to use this class instead of using raw pointer wherever possible.
*
* \note smart pointer to NULL is valid.
*
* \ingroup CodeLite
* \version 1.0
* first version
* \date 09-17-2006
* \author Eran
*/
template <class T> class SmartPtr
{
/**
* The reference counting class
*
* \ingroup CodeLite
* \version 1.0
* first version
*
* \date 09-17-2006
* \author Eran
*/
class SmartPtrRef
{
T* m_data;
int m_refCount;
public:
/**
* Construct a reference counting class for row pointer data
* \param data pointer
*/
SmartPtrRef(T* data)
: m_data(data)
, m_refCount(1)
{
}
/**
* Destructor
*/
virtual ~SmartPtrRef() { delete m_data; }
/**
* \return Pointer to the row data
*/
T* GetData() { return m_data; }
const T* GetData() const { return m_data; }
/**
* Increase reference counting by 1
*/
void IncRef() { m_refCount++; }
/**
* Decrease reference counting by 1
*/
void DecRef() { m_refCount--; }
/**
* Return the current reference counting
* \return current reference counting
*/
int GetRefCount() { return m_refCount; }
};
SmartPtrRef* m_ref;
public:
/**
* Construct smart pointer from ptr
* \param ptr pointer
*/
SmartPtr(T* ptr)
{
// create a fresh copy
CreateFresh(ptr);
}
/**
* Default constructor
*/
SmartPtr()
: m_ref(NULL)
{
}
/**
* Copy constructor
* \param rhs right hand side
*/
SmartPtr(const SmartPtr& rhs)
: m_ref(NULL)
{
*this = rhs;
}
/**
* Assignment operator
* \param rhs right hand side
* \return reference to this
*/
SmartPtr& operator=(const SmartPtr& rhs)
{
// increase the reference count
if(m_ref == rhs.m_ref) return *this;
// Delete previous reference
DeleteRefCount();
if(!rhs.m_ref) return *this;
m_ref = rhs.m_ref;
if(m_ref) {
m_ref->IncRef();
}
return *this;
}
/**
* Destructor
*/
virtual ~SmartPtr() { DeleteRefCount(); }
/**
* Replace the current pointer with ptr
* if the current ptr is not NULL, it will be freed (reference counting free) before assingning the new ptr
* \param ptr new pointer
*/
void Reset(T* ptr)
{
DeleteRefCount();
CreateFresh(ptr);
}
/**
* Return pointer the row data pointer
* \return pointer to the row data pointer
*/
T* Get() { return m_ref->GetData(); }
const T* Get() const { return m_ref->GetData(); }
/**
* Overload the '->' operator
* \return pointer to the row data pointer
*/
T* operator->() const { return m_ref->GetData(); }
/**
* Dereference operator
* \return dereference the row data
*/
T& operator*() const { return *(m_ref->GetData()); }
/**
* Test for NULL operator
* \return true if the internal row data or the reference counting class are NULL false otherwise
*/
bool operator!() const
{
if(!m_ref) return true;
return m_ref->GetData() == NULL;
}
/**
* test for bool operation
* \return true of the internal raw data exist and it is not null
*/
operator bool() const { return m_ref && m_ref->GetData(); }
private:
void DeleteRefCount()
{
// decrease the ref count (or delete pointer if it is 1)
if(m_ref) {
if(m_ref->GetRefCount() == 1) {
delete m_ref;
m_ref = NULL;
} else {
m_ref->DecRef();
}
}
};
void CreateFresh(T* ptr) { m_ref = new SmartPtrRef(ptr); }
};
#endif // CODELITE_SMART_PTR_H
|