00001 #ifndef ANP_HANDLE_H
00002 #define ANP_HANDLE_H
00003
00016
00017
00028
00029
00030 #include <iostream>
00031
00032 namespace Anp
00033 {
00034 class Base
00035 {
00036 public:
00037
00038 Base();
00039 virtual ~Base();
00040
00041 void add_ref();
00042
00043 void release();
00044
00045 unsigned int use_count() const;
00046
00047 private:
00048
00049
00050
00051 Base(const Base &);
00052 Base& operator=(const Base &);
00053
00054 private:
00055
00056 unsigned int fCount;
00057 };
00058
00059
00060
00061
00062 inline Base::Base() : fCount(0) {}
00063 inline Base::~Base() {}
00064
00065 inline void Base::add_ref() { ++fCount; }
00066 inline void Base::release() { if ( --fCount == 0 ) delete this; }
00067 inline unsigned int Base::use_count() const { return fCount; }
00068
00069
00070 template <typename T>
00071 class Handle
00072 {
00073 public:
00074
00078 Handle();
00079
00083 explicit Handle(T* ptr);
00084
00088 Handle(const Handle& rhs);
00089
00093 ~Handle();
00094
00098 const Handle& operator=(const Handle& rhs);
00099
00103 T* operator->() const;
00104
00108 T* get() const;
00109
00113 T& operator*() const;
00114
00118 bool valid() const;
00119
00123 void release();
00124
00125 private:
00126
00127 T* p;
00128
00129 void init();
00130 };
00131
00132
00133 template <typename T>
00134 Handle<T>::Handle() : p(0)
00135 {}
00136
00140 template <typename T>
00141 Handle<T>::Handle(T* realPtr) : p(realPtr)
00142 {
00143 init();
00144 }
00145
00149 template <typename T>
00150 Handle<T>::Handle(const Handle& rhs) : p(rhs.p)
00151 {
00152 init();
00153 }
00154
00155
00159 template <typename T>
00160 const Handle<T>& Handle<T>::operator=(const Handle& rhs)
00161 {
00162 if (p != rhs.p)
00163 {
00164 if (p)
00165 {
00166 p -> release();
00167 }
00168
00169 p = rhs.p;
00170 init();
00171 }
00172
00173 return *this;
00174 }
00175
00176
00180 template <typename T>
00181 void Handle<T>::init()
00182 {
00183 if (p)
00184 {
00185 p -> add_ref();
00186 }
00187 }
00188
00192 template <typename T>
00193 Handle<T>::~Handle()
00194 {
00195 if (p)
00196 {
00197 p -> release();
00198 }
00199 }
00200
00204 template <typename T>
00205 T* Handle<T>::operator->() const
00206 {
00207 return p;
00208 }
00209
00213 template <typename T>
00214 T* Handle<T>::get() const
00215 {
00216 return p;
00217 }
00218
00222 template <typename T>
00223 T& Handle<T>::operator*() const
00224 {
00225 return *p;
00226 }
00227
00231 template <typename T>
00232 bool Handle<T>::valid() const
00233 {
00234 if (p)
00235 {
00236 return true;
00237 }
00238
00239 return false;
00240 }
00241
00245 template <typename T>
00246 void Handle<T>::release()
00247 {
00248 if (p)
00249 {
00250 p -> release();
00251 }
00252 p = 0;
00253 }
00254
00258 template <typename T>
00259 std::ostream& operator<<(std::ostream& o, const Handle<T>& handle)
00260 {
00261 o << *handle;
00262 return o;
00263 }
00264
00265 }
00266
00267 #endif // HANDLE_H