00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef OMGUI_REFCOUNT_H
00024 #define OMGUI_REFCOUNT_H
00025
00026 #include <omgui/dllimpexp.h>
00027 #include <functional>
00028 #include <assert.h>
00029
00030 namespace omgui {
00031
00039 template<typename T> class Pointer
00040 {
00041 public:
00048 Pointer(T *p = 0, bool add_ref = true): m_p(p)
00049 {
00050 if( m_p != 0 && add_ref ) intrusive_ptr_add_ref(m_p);
00051 }
00052
00053 Pointer(const Pointer &p): m_p(p.m_p)
00054 {
00055 if( m_p != 0 ) intrusive_ptr_add_ref(m_p);
00056 }
00057
00058 template<typename U> Pointer(const Pointer<U> &p): m_p(p.get())
00059 {
00060 if( m_p != 0 ) intrusive_ptr_add_ref(m_p);
00061 }
00062
00063 ~Pointer()
00064 {
00065 if( m_p != 0 ) intrusive_ptr_release(m_p);
00066 }
00067
00068 T *operator-> () const
00069 {
00070 assert(m_p != 0);
00071 return m_p;
00072 }
00073
00074 T &operator* () const
00075 {
00076 assert(m_p != 0);
00077 return *m_p;
00078 }
00079
00080 T *get() const
00081 {
00082 return m_p;
00083 }
00084
00085 typedef T * Pointer::*unspecified_bool_type;
00086
00087 operator unspecified_bool_type () const
00088 {
00089 return m_p == 0 ? 0 : &Pointer::m_p;
00090 }
00091
00092 Pointer &operator= (const Pointer &p)
00093 {
00094 Pointer(p).swap(*this);
00095 return *this;
00096 }
00097
00098 template<typename U> Pointer &operator= (const Pointer<U> &p)
00099 {
00100 Pointer(p).swap(*this);
00101 return *this;
00102 }
00103
00104 private:
00105 T *m_p;
00106
00107 void swap(Pointer &p)
00108 {
00109 T *temp = m_p;
00110 m_p = p.m_p;
00111 p.m_p = temp;
00112 }
00113
00114 template<typename U> friend void swap(Pointer<U> &lhs, Pointer<U> &rhs);
00115 };
00116
00117 template<typename T, typename U> inline bool operator== (const Pointer<T> &lhs, const Pointer<U> &rhs)
00118 {
00119 return lhs.get() == rhs.get();
00120 }
00121
00122 template<typename T, typename U> inline bool operator!= (const Pointer<T> &lhs, const Pointer<U> &rhs)
00123 {
00124 return lhs.get() != rhs.get();
00125 }
00126
00127 template<typename T, typename U> inline bool operator== (const Pointer<T> &lhs, U *rhs)
00128 {
00129 return lhs.get() == rhs;
00130 }
00131
00132 template<typename T, typename U> inline bool operator!= (const Pointer<T> &lhs, U *rhs)
00133 {
00134 return lhs.get() != rhs;
00135 }
00136
00137 template<typename T, typename U> inline bool operator== (T *lhs, const Pointer<U> &rhs)
00138 {
00139 return lhs == rhs.get();
00140 }
00141
00142 template<typename T, typename U> inline bool operator!= (T *lhs, const Pointer<U> &rhs)
00143 {
00144 return lhs != rhs.get();
00145 }
00146
00147 template<typename T> inline bool operator< (const Pointer<T> &lhs, const Pointer<T> &rhs)
00148 {
00149 return std::less<T>(lhs.get(), rhs.get());
00150 }
00151
00152 template<typename U> void swap(Pointer<U> &lhs, Pointer<U> &rhs)
00153 {
00154 lhs.swap(rhs);
00155 }
00156
00162 class OMGUI_API RefCountable
00163 {
00164 public:
00165 RefCountable() { }
00166 virtual ~RefCountable() { }
00167
00168 virtual void add_ref() = 0;
00169 virtual void release() = 0;
00170 };
00171
00177 class OMGUI_API RefCounted : public RefCountable
00178 {
00179 public:
00180 RefCounted();
00181
00182 void add_ref();
00183 void release();
00184
00185 private:
00186 int m_ref_count;
00187 };
00188
00189 }
00190
00194 void OMGUI_API intrusive_ptr_add_ref(omgui::RefCountable *countable);
00195
00199 void OMGUI_API intrusive_ptr_release(omgui::RefCountable *countable);
00200
00201 #endif