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 #ifndef _BASE_REF_
00026 #define _BASE_REF_
00027
00028
00029 #include <functional>
00030 #include <typeinfo>
00031 #include <stdexcept>
00032
00033 namespace base
00034 {
00035
00036 namespace detail
00037 {
00038 struct static_cast_tag {};
00039 struct dynamic_cast_tag {};
00040 }
00041
00042
00043
00044 template<typename T>
00045 class ref
00046 {
00047 public:
00048 typedef T element_type;
00049 typedef T* pointer;
00050 typedef T& reference;
00051
00052 ref()
00053 : p(pointer(0))
00054 {}
00055
00056
00057 explicit ref(pointer p)
00058 : p(p)
00059 {
00060 if (p) p->reference();
00061 }
00062
00063
00064 ref(const ref& r)
00065 : p(r.p)
00066 {
00067 if (p) p->reference();
00068 }
00069
00070 template<typename T2>
00071 ref(const ref<T2>& r)
00072 : p(r.get())
00073 {
00074 if (p) p->reference();
00075 }
00076
00077
00078 template<typename T2>
00079 ref(const ref<T2>& r, detail::static_cast_tag)
00080 {
00081 p = static_cast<pointer>(r.get());
00082 if (p) p->reference();
00083 }
00084
00085 template<typename T2>
00086 ref(const ref<T2>& r, detail::dynamic_cast_tag)
00087 {
00088 p = dynamic_cast<pointer>(r.get());
00089 if (r.get() && (!p)) throw std::bad_cast();
00090 if (p) p->reference();
00091 }
00092
00093
00094
00095 ~ref()
00096 {
00097 if (p)
00098 if (p->unreference())
00099 delete p;
00100 }
00101
00102 ref& operator=(const ref& r)
00103 {
00104 if (&r != this) {
00105 if (p)
00106 if (p->unreference())
00107 delete p;
00108 p=r.p;
00109 if (p) p->reference();
00110 }
00111 return *this;
00112 }
00113
00114 template<typename T2>
00115 ref& operator=(const ref<T2>& r)
00116 {
00117 if (r.get() != this->get()) {
00118 if (p)
00119 if (p->unreference())
00120 delete p;
00121 p=r.get();
00122 if (p) p->reference();
00123 }
00124 return *this;
00125 }
00126
00127 pointer get() const { return p; }
00128
00129 void reset(pointer p = pointer(0))
00130 {
00131 if (p == this->p) {
00132 #ifdef DEBUG
00133 std::cerr << "can't reset to same pointer\n"; abort();
00134 #else
00135 throw std::runtime_error("can't reset to same pointer");
00136 #endif
00137 }
00138 if (this->p)
00139 if (this->p->unreference())
00140 delete this->p;
00141 this->p = p;
00142 }
00143
00144
00145 pointer release()
00146 {
00147 pointer rp = p;
00148 if (p)
00149 if (p->unreference())
00150 delete p;
00151 p = pointer(0);
00152 return rp;
00153 }
00154
00155 void swap(ref& r) { std::swap(r.p, p); }
00156
00157
00158 bool operator==(const ref& r) const { return p == r.p; }
00159 bool operator!=(const ref& r) const { return p != r.p; }
00160
00161 template<typename T2>
00162 bool operator==(const ref<T2>& r) const { return p == r.get(); }
00163
00164 template<typename T2>
00165 bool operator!=(const ref<T2>& r) const { return p != r.get(); }
00166
00167 template<typename T2>
00168 bool operator==(const T2* p2) const { return p == p2; }
00169
00170 template<typename T2>
00171 bool operator!=(const T2* p2) const { return p != p2; }
00172
00173
00174 reference operator*()
00175 {
00176 if (!p) {
00177 #ifdef DEBUG
00178 std::cerr << "null pointer\n"; abort();
00179 #else
00180 throw std::runtime_error("null pointer");
00181 #endif
00182 }
00183 return *p;
00184 }
00185
00186 reference operator*() const
00187 {
00188 if (!p) {
00189 #ifdef DEBUG
00190 std::cerr << "null pointer\n"; abort();
00191 #else
00192 throw std::runtime_error("null pointer");
00193 #endif
00194 }
00195 return *p;
00196 }
00197
00198 pointer operator->()
00199 {
00200 if (!p) {
00201 #ifdef DEBUG
00202 std::cerr << "null pointer\n"; abort();
00203 #else
00204 throw std::runtime_error("null pointer");
00205 #endif
00206 }
00207 return p;
00208 }
00209
00210 pointer operator->() const
00211 {
00212 if (!p) {
00213 #ifdef DEBUG
00214 std::cerr << "null pointer\n"; abort();
00215 #else
00216 throw std::runtime_error("null pointer");
00217 #endif
00218 }
00219 return p;
00220 }
00221
00222 bool operator!() const { return p == 0; }
00223
00224 private:
00225
00226 struct Tester
00227 {
00228 Tester() {}
00229 private:
00230 void operator delete(void*);
00231 };
00232
00233 public:
00234
00235 operator Tester*() const
00236 {
00237 if (!*this) return 0;
00238 static Tester t;
00239 return &t;
00240 }
00241
00242 protected:
00243 pointer p;
00244 };
00245
00246
00247 template<typename T>
00248 inline void Release(ref<T>& r) { r.release(); }
00249
00250 template<typename T>
00251 inline typename ref<T>::pointer GetImplRef(ref<T>& r) { return r.get(); }
00252
00253 template<typename T>
00254 inline void Reset(ref<T>& r, const typename ref<T>::pointer p) { r.reset(p); }
00255
00256
00257 template<class T, class U> inline bool operator==(const ref<T>& a, const ref<U>& b)
00258 {
00259 return a.get() == b.get();
00260 }
00261
00262 template<class T, class U> inline bool operator==(const T* a, const ref<U>& b)
00263 {
00264 return a == b.get();
00265 }
00266
00267 template<class T, class U> inline bool operator==(const ref<T>& a, const U* b)
00268 {
00269 return a.get() == b;
00270 }
00271
00272 template<class T, class U> inline bool operator!=(const ref<T>& a, const ref<U>& b)
00273 {
00274 return a.get() != b.get();
00275 }
00276
00277 template<class T, class U> inline bool operator!=(const T* a, const ref<U>& b)
00278 {
00279 return a != b.get();
00280 }
00281
00282 template<class T, class U> inline bool operator!=(const ref<T>& a, const U* b)
00283 {
00284 return a.get() != b;
00285 }
00286
00287
00288
00289 template<class T, class U> inline bool operator<(const ref<T>& a, const ref<U>& b)
00290 {
00291 return a.get() < b.get();
00292 }
00293
00294 template<class T, class U> inline bool operator<(const T* a, const ref<U>& b)
00295 {
00296 return a < b.get();
00297 }
00298
00299 template<class T, class U> inline bool operator<(const ref<T>& a, const U* b)
00300 {
00301 return a.get() < b;
00302 }
00303
00304
00305 template<class T, class U> inline bool operator>(const ref<T>& a, const ref<U>& b)
00306 {
00307 return a.get() > b.get();
00308 }
00309
00310 template<class T, class U> inline bool operator>(const T* a, const ref<U>& b)
00311 {
00312 return a > b.get();
00313 }
00314
00315 template<class T, class U> inline bool operator>(const ref<T>& a, const U* b)
00316 {
00317 return a.get() > b;
00318 }
00319
00320
00321
00322 template<class T, class U> inline bool operator<=(const ref<T>& a, const ref<U>& b)
00323 {
00324 return a.get() <= b.get();
00325 }
00326
00327 template<class T, class U> inline bool operator<=(const T* a, const ref<U>& b)
00328 {
00329 return a <= b.get();
00330 }
00331
00332 template<class T, class U> inline bool operator<=(const ref<T>& a, const U* b)
00333 {
00334 return a.get() <= b;
00335 }
00336
00337
00338 template<class T, class U> inline bool operator>=(const ref<T>& a, const ref<U>& b)
00339 {
00340 return a.get() >= b.get();
00341 }
00342
00343 template<class T, class U> inline bool operator>=(const T* a, const ref<U>& b)
00344 {
00345 return a >= b.get();
00346 }
00347
00348 template<class T, class U> inline bool operator>=(const ref<T>& a, const U* b)
00349 {
00350 return a.get() >= b;
00351 }
00352
00353
00354
00355
00356
00357
00358 template<class T, class U> ref<T> static_cast_ref(const ref<U>& r)
00359 {
00360 return ref<T>(r, detail::static_cast_tag());
00361 }
00362
00363 template<class T, class U> ref<T> narrow_cast_ref(const ref<U>& r)
00364 {
00365 return ref<T>(r, detail::dynamic_cast_tag());
00366 }
00367
00368 template<class T, class U> ref<T> dynamic_cast_ref(const ref<U>& r)
00369 {
00370 return ref<T>(r, detail::dynamic_cast_tag());
00371 }
00372
00373 #define narrow_ref narrow_cast_ref
00374
00375
00376 }
00377
00378
00379
00380
00381 namespace std
00382 {
00383
00384 template<typename T>
00385 struct less< base::ref<T> >
00386 : public binary_function<base::ref<T>, base::ref<T>, bool>
00387 {
00388 bool operator()(const base::ref<T>& lhs, const base::ref<T>& rhs) const
00389 { return less<T*>()(lhs.get(), rhs.get()); }
00390 };
00391
00392 }
00393
00394
00395 #endif
00396