jigdo API
Last update by Admin on 2010-05-23
util/smartptr.hh
Go to the documentation of this file.00001 /* $Id: smartptr.hh,v 1.3 2003/08/30 17:56:11 richard Exp $ -*- C++ -*- 00002 __ _ 00003 |_) /| Copyright (C) 2000-2004 | richard@ 00004 | \/¯| Richard Atterer | atterer.net 00005 ¯ '` ¯ 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License, version 2 or 00008 later. See the file COPYING for details. 00009 00010 */ 00018 #ifndef SMARTPTR_HH 00019 #define SMARTPTR_HH 00020 00021 #ifdef DEBUG 00022 # include <cstdlib> 00023 # include <iostream> 00024 #endif 00025 //______________________________________________________________________ 00026 00027 struct SmartPtr_lockStatic; 00028 00037 struct SmartPtrBase { 00038 //friend template class<X> SmartPtr<X>; 00039 friend struct SmartPtr_lockStatic; 00040 SmartPtrBase() /*throw()*/ : smartPtr_refCount(0) { } 00041 int smartPtr_refCount; 00042 }; 00043 00044 /* The version of SmartPtrBase below needs the following: 00045 class Base : virtual public SmartPtrBase<Base> { ... }; 00046 class Derived : virtual public SmartPtrBase<Derived>, public Base { ... }; 00047 in order to allow a Derived object's address to be assigned to a 00048 SmartPtr<Base>. */ 00049 // template<class X> class SmartPtr; 00050 // 00051 // template<class X> 00052 // class SmartPtrBase { 00053 // friend class SmartPtr<X>; 00054 // public: 00055 // SmartPtrBase() /*throw()*/ : smartPtr_refCount(0) { } 00056 // private: 00057 // int smartPtr_refCount; 00058 // }; 00059 //______________________________________________________________________ 00060 00066 struct SmartPtr_lockStatic { 00067 SmartPtr_lockStatic(SmartPtrBase& obj) { ++obj.smartPtr_refCount; } 00068 ~SmartPtr_lockStatic() { } 00069 }; 00070 //______________________________________________________________________ 00071 00088 template<class X> 00089 class SmartPtr { 00090 public: 00091 typedef X element_type; 00092 00093 SmartPtr() : ptr(0) { 00094 # ifdef DEBUG_SMARTPTR 00095 cerr << this << " SmartPtr()" << endl; 00096 # endif 00097 } 00098 ~SmartPtr() { 00099 # ifdef DEBUG_SMARTPTR 00100 cerr << this << " ~SmartPtr() " << ptr << "/" 00101 << (ptr == 0 ? 0 : ptr->smartPtr_refCount) << endl; 00102 # endif 00103 decRef(); 00104 } 00105 00106 // init from SmartPtr<X> 00107 SmartPtr(const SmartPtr& x) : ptr(x.get()) { 00108 # ifdef DEBUG_SMARTPTR 00109 cerr << this << " SmartPtr(SP " << x.get() << ")" << endl; 00110 # endif 00111 incRef(); 00112 } 00113 // init from SmartPtr to other type; only works if implicit conv. possible 00114 template<class Y> SmartPtr(const SmartPtr<Y>& y) : ptr(y.get()) { 00115 # ifdef DEBUG_SMARTPTR 00116 cerr << this << " SmartPtr(SP<Y> " << y.get() << ")" << endl; 00117 # endif 00118 incRef(); 00119 } 00120 // init from pointer 00121 explicit SmartPtr(X* x) : ptr(x) { 00122 # ifdef DEBUG_SMARTPTR 00123 cerr << this << " SmartPtr(" << x << ")" << endl; 00124 # endif 00125 incRef(); 00126 } 00127 00128 /* This one is necessary, the compiler will *not* generate one from 00129 the template below. */ 00130 SmartPtr& operator=(const SmartPtr& x) { 00131 # ifdef DEBUG_SMARTPTR 00132 cerr << this << " SmartPtr " << ptr << " = SP<X> " << x.get() << endl; 00133 # endif 00134 if (ptr != x.get()) { decRef(); ptr = x.get(); incRef(); } 00135 return *this; 00136 } 00137 template<class Y> SmartPtr& operator=(const SmartPtr<Y>& y) { 00138 # ifdef DEBUG_SMARTPTR 00139 cerr << this << " SmartPtr " << ptr << " = SP<Y> " << y.get() << endl; 00140 # endif 00141 if (ptr != y.get()) { decRef(); ptr = y.get(); incRef(); } 00142 return *this; 00143 } 00144 template<class Y> SmartPtr& operator=(Y* y) { 00145 # ifdef DEBUG_SMARTPTR 00146 cerr << this << " SmartPtr " << ptr << " = " << y << endl; 00147 # endif 00148 if (ptr != y) { decRef(); ptr = y; incRef(); } 00149 return *this; 00150 } 00151 00152 X& operator*() const { return *ptr; } 00153 X* operator->() const { return ptr; } 00154 X* get() const { return ptr; } 00155 X* release() { // relinquish ownership, but never delete 00156 # ifdef DEBUG 00157 if (ptr != 0 && ptr->SmartPtrBase::smartPtr_refCount == 0) 00158 abort(); 00159 # endif 00160 if (ptr != 0) --(ptr->SmartPtrBase::smartPtr_refCount); 00161 X* tmp = ptr; ptr = 0; return tmp; 00162 } 00163 void swap(SmartPtr& x) { X* tmp = ptr; ptr = x.ptr; x.ptr = tmp; } 00164 void clear() { decRef(); ptr = 0; } 00165 bool isNull() const { return ptr == 0; } 00166 00167 private: 00168 void incRef() { 00169 if (ptr != 0) ++(ptr->SmartPtrBase::smartPtr_refCount); 00170 } 00171 void decRef() { 00172 # ifdef DEBUG 00173 if (ptr != 0 && ptr->SmartPtrBase::smartPtr_refCount == 0) 00174 abort(); 00175 # endif 00176 if (ptr != 0 && --(ptr->SmartPtrBase::smartPtr_refCount) <= 0) 00177 delete ptr; 00178 } 00179 X* ptr; 00180 }; 00181 //____________________ 00182 00183 template<class X> 00184 inline SmartPtr<X> makeSmartPtr(X* x) { return SmartPtr<X>(x); } 00185 00186 // only delete if count is zero 00187 // 'deleteSmart(x);' is equivalent to '{ SmartPtr<X> tmp(x); }' 00188 template<class X> // need template for 'delete ptr' to call the right dtor 00189 inline bool deleteSmart(X* ptr) { 00190 if (ptr != 0 && ptr->SmartPtrBase::smartPtr_refCount <= 0) { 00191 delete ptr; return true; 00192 } else { 00193 return false; 00194 } 00195 } 00196 00197 template<class X> 00198 inline X* releaseSmart(X* ptr) { 00199 if (ptr != 0) --ptr->SmartPtrBase::smartPtr_refCount; 00200 return ptr; 00201 } 00202 //____________________ 00203 00204 template<class X> inline void swap(SmartPtr<X>& a, SmartPtr<X>& b) { 00205 a.swap(b); 00206 } 00207 template<class X> 00208 inline bool operator<(const SmartPtr<X> a, const SmartPtr<X> b) { 00209 return a.get() < b.get(); 00210 } 00211 template<class X> 00212 inline bool operator>(const SmartPtr<X> a, const SmartPtr<X> b) { 00213 return a.get() > b.get(); 00214 } 00215 template<class X> 00216 inline bool operator<=(const SmartPtr<X> a, const SmartPtr<X> b) { 00217 return a.get() <= b.get(); 00218 } 00219 template<class X> 00220 inline bool operator>=(const SmartPtr<X> a, const SmartPtr<X> b) { 00221 return a.get() >= b.get(); 00222 }; 00223 00224 // allow comparison with pointers 00225 template<class X> 00226 inline bool operator==(const SmartPtr<X> a, const void* b) { 00227 return a.get() == b; 00228 } 00229 template<class X> 00230 inline bool operator==(const void* a, const SmartPtr<X> b) { 00231 return a == b.get(); 00232 } 00233 template<class X> 00234 inline bool operator!=(const SmartPtr<X> a, const void* b) { 00235 return a.get() != b; 00236 } 00237 template<class X> 00238 inline bool operator!=(const void* a, const SmartPtr<X> b) { 00239 return a != b.get(); 00240 } 00241 #endif
Generated on Tue Sep 23 14:27:42 2008 for jigdo by
