Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef WAVEPACKET_SMART_PTR_H__
00037 #define WAVEPACKET_SMART_PTR_H__
00038
00039
00040
00041 #include "threadsafe_counter.h"
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 template <class T>
00069 class smart_ptr
00070 {
00071 public:
00072
00073 smart_ptr(T * pT = NULL) throw() : m_prefcount(NULL), m_pT(NULL) {
00074 this->assign(pT);
00075 }
00076
00077 template <class X>
00078 smart_ptr(IN const smart_ptr<X>& from) throw() :
00079 m_prefcount(NULL), m_pT(NULL) {
00080 this->assign(from);
00081 }
00082
00083 smart_ptr(IN const smart_ptr<T>& from) throw() :
00084 m_prefcount(NULL), m_pT(NULL) {
00085 this->assign(from);
00086 }
00087
00088
00089 ~smart_ptr(void) throw() { this->release(); }
00090
00091
00092 T * operator -> (void) throw() {
00093 ASSERT(m_pT, "NULL smart pointer");
00094 return m_pT;
00095 }
00096
00097 const T * operator -> (void) const throw() {
00098 ASSERT(m_pT, "NULL smart pointer");
00099 return m_pT;
00100 }
00101
00102 operator T * (void) throw() {
00103 return m_pT;
00104 }
00105
00106 operator const T * (void) const throw() {
00107 return m_pT;
00108 }
00109
00110 bool operator ! (void) const throw() {
00111 return !m_pT;
00112 }
00113
00114 const smart_ptr<T>& operator = (IN T * pT) throw() {
00115 this->assign(pT);
00116 return *this;
00117 }
00118
00119 template <class X>
00120 const smart_ptr<T>& operator = (IN const smart_ptr<X>& from) throw() {
00121 this->assign(from);
00122 return *this;
00123 }
00124
00125 const smart_ptr<T>& operator = (IN const smart_ptr<T>& from) throw() {
00126 this->assign(from);
00127 return *this;
00128 }
00129
00130 long get_ref_count(void) const throw() {
00131 return (m_prefcount) ? m_prefcount->getCount() : 0;
00132 }
00133
00134 T * disown(void) throw() {
00135
00136
00137 ASSERT(m_prefcount && m_pT,
00138 "calling disown() on empty smart_ptr<T>");
00139 ASSERT(!m_prefcount->decrement(),
00140 "Can only disown() smart_ptr<T>'s with 1 ref");
00141 delete m_prefcount;
00142 m_prefcount = NULL;
00143 T * pT = m_pT;
00144 m_pT = NULL;
00145 return pT;
00146 }
00147
00148 private:
00149
00150
00151
00152 void assign(IN T * pT) throw() {
00153 this->release();
00154 if (pT) {
00155 m_prefcount = new threadsafe_counter;
00156 ASSERT(m_prefcount, "out of memory");
00157 m_prefcount->increment();
00158 m_pT = pT;
00159 }
00160 }
00161
00162 template <class X>
00163 void assign(IN const smart_ptr<X>& from) throw() {
00164 this->release();
00165
00166
00167 smart_ptr<T> * pfoo =
00168 (smart_ptr<T> *) ((void *) &from);
00169
00170
00171
00172
00173
00174 long incCount = pfoo->increment();
00175 if (incCount < 2) {
00176
00177 pfoo->decrement();
00178 return;
00179 }
00180
00181
00182
00183
00184
00185 const X * pX = (const X *) from;
00186 const T * pT = dynamic_cast<const T *>(pX);
00187 if (!pT) {
00188
00189 pfoo->decrement();
00190 return;
00191 }
00192
00193
00194 ASSERT(pT, "should have non-null pointer");
00195
00196
00197 T * new_pT = (T *) pT;
00198
00199
00200 m_prefcount = pfoo->m_prefcount;
00201 m_pT = new_pT;
00202
00203
00204
00205 }
00206
00207 void release(void) throw() {
00208 if (m_prefcount) {
00209
00210 long count = m_prefcount->decrement();
00211 if (count < 1) {
00212
00213 m_prefcount->increment();
00214 delete m_pT;
00215 delete m_prefcount;
00216 }
00217
00218
00219 m_prefcount = NULL;
00220 m_pT = NULL;
00221 }
00222 ASSERT(!m_pT && !m_prefcount, "Invalid release");
00223 }
00224
00225 long increment(void) throw() {
00226 if (m_prefcount) {
00227 return m_prefcount->increment();
00228 }
00229 return 0;
00230 }
00231
00232 long decrement(void) throw() {
00233 if (m_prefcount) {
00234 return m_prefcount->decrement();
00235 }
00236 return 0;
00237 }
00238
00239
00240 threadsafe_counter * m_prefcount;
00241 T *m_pT;
00242 };
00243
00244
00245
00246 #endif // WAVEPACKET_SMART_PTR_H__
00247