refcount.h

Go to the documentation of this file.
00001 
00007 /*
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Lesser General Public
00010     License as published by the Free Software Foundation; either
00011     version 2.1 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Lesser General Public License for more details.
00017 
00018     You should have received a copy of the GNU Lesser General Public
00019     License along with this library; if not, write to the Free Software
00020     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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

doxygen SourceForge.net Logo