ref_ptr.h

00001 // ref_ptr.h                                       -*-c++-*-
00002 //
00003 // A reference-counting pointer.  The object behind the pointer should
00004 // implement incref() and decref(); the pointer arranges for these
00005 // methods to be called at the appropriate times.
00006 
00007 #ifndef REF_PTR_H
00008 #define REF_PTR_H
00009 
00010 #include <sigc++/reference_wrapper.h>
00011 
00012 #include <cwidget/generic/util/eassert.h>
00013 
00014 namespace cwidget
00015 {
00016   namespace util
00017   {
00018     template<class T>
00019     class ref_ptr
00020     {
00021       T *ref;
00022 
00023     public:
00024       ref_ptr(T *_ref)
00025         :ref(_ref)
00026       {
00027         if(ref != 0)
00028           ref->incref();
00029       }
00030 
00031       ref_ptr(const ref_ptr &other)
00032         :ref(other.ref)
00033       {
00034         if(ref != 0)
00035           ref->incref();
00036       }
00037 
00038       template<class S>
00039       ref_ptr(const ref_ptr<S> &other)
00040         :ref(other.unsafe_get_ref())
00041       {
00042         if(ref != 0)
00043           ref->incref();
00044       }
00045 
00046       ref_ptr()
00047         :ref(0)
00048       {
00049       }
00050 
00051       ~ref_ptr()
00052       {
00053         if(ref != 0)
00054           ref->decref();
00055       }
00056 
00057       ref_ptr &operator=(const ref_ptr &other)
00058       {
00059         if(other.ref != 0)
00060           other.ref->incref();
00061 
00062         if(ref != 0)
00063           ref->decref();
00064 
00065         ref = other.ref;
00066 
00067         return *this;
00068       }
00069 
00070       const sigc::reference_wrapper<T> weak_ref() const
00071       {
00072         eassert(ref != 0);
00073 
00074         return sigc::ref(*ref);
00075       }
00076 
00077       // If S is assignment-compatible with T and both have
00078       // reference-counting methods, perform this assignment.
00079       //
00080       // Read: upcasting pointers.
00081       template<class S>
00082       ref_ptr<T> &operator=(const ref_ptr<S> &other)
00083       {
00084         S * const other_ref = other.unsafe_get_ref();
00085 
00086         if(other_ref != 0)
00087           other_ref->incref();
00088 
00089         if(ref != 0)
00090           ref->decref();
00091 
00092         ref = other_ref;
00093 
00094         return *this;
00095       }
00096 
00097       template<class S>
00098       bool operator==(const ref_ptr<S> &other) const
00099       {
00100         return ref == other.unsafe_get_ref();
00101       }
00102 
00103       template<class S>
00104       bool operator!=(const ref_ptr<S> &other) const
00105       {
00106         return ref != other.unsafe_get_ref();
00107       }
00108 
00109       template<class S>
00110       bool operator<(const ref_ptr<S> &other) const
00111       {
00112         return ref < other.unsafe_get_ref();
00113       }
00114 
00115       template<class S>
00116       bool operator>(const ref_ptr<S> &other) const
00117       {
00118         return ref > other.unsafe_get_ref();
00119       }
00120 
00121       template<class S>
00122       bool operator<=(const ref_ptr<S> &other) const
00123       {
00124         return ref <= other.unsafe_get_ref();
00125       }
00126 
00127       template<class S>
00128       bool operator>=(const ref_ptr<S> &other) const
00129       {
00130         return ref >= other.unsafe_get_ref();
00131       }
00132 
00133       // Safe downcasting.
00134       template<class S>
00135       ref_ptr<S> dyn_downcast() const
00136       {
00137         return ref_ptr<S>(dynamic_cast<S*>(ref));
00138       }
00139 
00140       void clear()
00141       {
00142         (*this) = 0;
00143       }
00144 
00145       bool valid() const
00146       {
00147         return ref != 0;
00148       }
00149 
00150       T *operator->() const
00151       {
00152         return ref;
00153       }
00154 
00159       T *unsafe_get_ref() const
00160       {
00161         return ref;
00162       }
00163     };
00164   }
00165 }
00166 
00167 #endif

Generated on Mon Jul 7 11:11:54 2008 for cwidget by  doxygen 1.5.6