00001
00002 #ifndef _cairo_REFPTR_H
00003 #define _cairo_REFPTR_H
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 namespace Cairo
00027 {
00028
00041 template <class T_CppObject>
00042 class RefPtr
00043 {
00044 public:
00049 inline RefPtr();
00050
00052 inline ~RefPtr();
00053
00065 explicit inline RefPtr(T_CppObject* pCppObject);
00066
00071 inline RefPtr(const RefPtr<T_CppObject>& src);
00072
00077 template <class T_CastFrom>
00078 inline RefPtr(const RefPtr<T_CastFrom>& src);
00079
00085 inline void swap(RefPtr<T_CppObject>& other);
00086
00088 inline RefPtr<T_CppObject>& operator=(const RefPtr<T_CppObject>& src);
00089
00094 template <class T_CastFrom>
00095 inline RefPtr<T_CppObject>& operator=(const RefPtr<T_CastFrom>& src);
00096
00098 inline bool operator==(const RefPtr<T_CppObject>& src) const;
00099
00101 inline bool operator!=(const RefPtr<T_CppObject>& src) const;
00102
00108 inline T_CppObject* operator->() const;
00109
00118 inline operator bool() const;
00119
00121 inline void clear();
00122
00123
00131 template <class T_CastFrom>
00132 static inline RefPtr<T_CppObject> cast_dynamic(const RefPtr<T_CastFrom>& src);
00133
00141 template <class T_CastFrom>
00142 static inline RefPtr<T_CppObject> cast_static(const RefPtr<T_CastFrom>& src);
00143
00151 template <class T_CastFrom>
00152 static inline RefPtr<T_CppObject> cast_const(const RefPtr<T_CastFrom>& src);
00153
00154
00155 #ifndef DOXYGEN_IGNORE_THIS
00156
00157
00158
00159 inline int* refcount_() const { return pCppRefcount_; }
00160
00161 #endif // DOXYGEN_IGNORE_THIS
00162
00163 private:
00164 void unref();
00165
00166 T_CppObject* pCppObject_;
00167 mutable int* pCppRefcount_;
00168 };
00169
00170
00171 #ifndef DOXYGEN_IGNORE_THIS
00172
00173
00174
00175
00176 template <class T_CppObject> inline
00177 T_CppObject* RefPtr<T_CppObject>::operator->() const
00178 {
00179 return pCppObject_;
00180 }
00181
00182 template <class T_CppObject> inline
00183 RefPtr<T_CppObject>::RefPtr()
00184 :
00185 pCppObject_(0),
00186 pCppRefcount_(0)
00187 {}
00188
00189 template <class T_CppObject> inline
00190 RefPtr<T_CppObject>::~RefPtr()
00191 {
00192 unref();
00193 }
00194
00195 template <class T_CppObject> inline
00196 void RefPtr<T_CppObject>::unref()
00197 {
00198 if(pCppRefcount_)
00199 {
00200 --(*pCppRefcount_);
00201
00202 if(*pCppRefcount_ == 0)
00203 {
00204 if(pCppObject_)
00205 {
00206 delete pCppObject_;
00207 pCppObject_ = 0;
00208 }
00209
00210 delete pCppRefcount_;
00211 pCppRefcount_ = 0;
00212 }
00213 }
00214 }
00215
00216
00217 template <class T_CppObject> inline
00218 RefPtr<T_CppObject>::RefPtr(T_CppObject* pCppObject)
00219 :
00220 pCppObject_(pCppObject),
00221 pCppRefcount_(0)
00222 {
00223 if(pCppObject)
00224 {
00225 pCppRefcount_ = new int;
00226 *pCppRefcount_ = 1;
00227 }
00228 }
00229
00230 template <class T_CppObject> inline
00231 RefPtr<T_CppObject>::RefPtr(const RefPtr<T_CppObject>& src)
00232 :
00233 pCppObject_ (src.pCppObject_),
00234 pCppRefcount_(src.pCppRefcount_)
00235 {
00236 if(pCppObject_ && pCppRefcount_)
00237 ++(*pCppRefcount_);
00238 }
00239
00240
00241
00242
00243 template <class T_CppObject>
00244 template <class T_CastFrom>
00245 inline
00246 RefPtr<T_CppObject>::RefPtr(const RefPtr<T_CastFrom>& src)
00247 :
00248
00249
00250
00251 pCppObject_ (src.operator->()),
00252 pCppRefcount_(src.refcount_())
00253 {
00254 if(pCppObject_ && pCppRefcount_)
00255 ++(*pCppRefcount_);
00256 }
00257
00258 template <class T_CppObject> inline
00259 void RefPtr<T_CppObject>::swap(RefPtr<T_CppObject>& other)
00260 {
00261 T_CppObject *const temp = pCppObject_;
00262 int* temp_count = pCppRefcount_;
00263
00264 pCppObject_ = other.pCppObject_;
00265 pCppRefcount_ = other.pCppRefcount_;
00266
00267 other.pCppObject_ = temp;
00268 other.pCppRefcount_ = temp_count;
00269 }
00270
00271 template <class T_CppObject> inline
00272 RefPtr<T_CppObject>& RefPtr<T_CppObject>::operator=(const RefPtr<T_CppObject>& src)
00273 {
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 RefPtr<T_CppObject> temp (src);
00299 this->swap(temp);
00300 return *this;
00301 }
00302
00303 template <class T_CppObject>
00304 template <class T_CastFrom>
00305 inline
00306 RefPtr<T_CppObject>& RefPtr<T_CppObject>::operator=(const RefPtr<T_CastFrom>& src)
00307 {
00308 RefPtr<T_CppObject> temp (src);
00309 this->swap(temp);
00310 return *this;
00311 }
00312
00313 template <class T_CppObject> inline
00314 bool RefPtr<T_CppObject>::operator==(const RefPtr<T_CppObject>& src) const
00315 {
00316 return (pCppObject_ == src.pCppObject_);
00317 }
00318
00319 template <class T_CppObject> inline
00320 bool RefPtr<T_CppObject>::operator!=(const RefPtr<T_CppObject>& src) const
00321 {
00322 return (pCppObject_ != src.pCppObject_);
00323 }
00324
00325 template <class T_CppObject> inline
00326 RefPtr<T_CppObject>::operator bool() const
00327 {
00328 return (pCppObject_ != 0);
00329 }
00330
00331 template <class T_CppObject> inline
00332 void RefPtr<T_CppObject>::clear()
00333 {
00334 RefPtr<T_CppObject> temp;
00335 this->swap(temp);
00336 }
00337
00338 template <class T_CppObject>
00339 template <class T_CastFrom>
00340 inline
00341 RefPtr<T_CppObject> RefPtr<T_CppObject>::cast_dynamic(const RefPtr<T_CastFrom>& src)
00342 {
00343 T_CppObject *const pCppObject = dynamic_cast<T_CppObject*>(src.operator->());
00344
00345 if(pCppObject && src.pCppRefcount_)
00346 ++(*(src.pCppRefcount_));
00347
00348 return RefPtr<T_CppObject>(pCppObject);
00349 }
00350
00351 template <class T_CppObject>
00352 template <class T_CastFrom>
00353 inline
00354 RefPtr<T_CppObject> RefPtr<T_CppObject>::cast_static(const RefPtr<T_CastFrom>& src)
00355 {
00356 T_CppObject *const pCppObject = static_cast<T_CppObject*>(src.operator->());
00357
00358 if(pCppObject && src.pCppRefcount_)
00359 ++(*(src.pCppRefcount_));
00360
00361 return RefPtr<T_CppObject>(pCppObject);
00362 }
00363
00364 template <class T_CppObject>
00365 template <class T_CastFrom>
00366 inline
00367 RefPtr<T_CppObject> RefPtr<T_CppObject>::cast_const(const RefPtr<T_CastFrom>& src)
00368 {
00369 T_CppObject *const pCppObject = const_cast<T_CppObject*>(src.operator->());
00370
00371 if(pCppObject && src.pCppRefcount_)
00372 ++(*(src.pCppRefcount_));
00373
00374 return RefPtr<T_CppObject>(pCppObject);
00375 }
00376
00377 #endif
00378
00380 template <class T_CppObject> inline
00381 void swap(RefPtr<T_CppObject>& lhs, RefPtr<T_CppObject>& rhs)
00382 {
00383 lhs.swap(rhs);
00384 }
00385
00386 }
00387
00388
00389 #endif
00390
00391