cwidget 0.5.16
|
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