00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024 #ifndef SHREFCOUNT_HPP
00025 #define SHREFCOUNT_HPP
00026
00027 #include <utility>
00028 #include "ShDllExport.hpp"
00029
00030
00031
00032 #ifdef SH_REFCOUNT_DEBUGGING
00033 #include <iostream>
00034 #include <iomanip>
00035 #include "ShDebug.hpp"
00036
00037 #define SH_RCDEBUG_GREEN std::cerr << "[32m"
00038 #define SH_RCDEBUG_RED std::cerr << "[31m"
00039 #define SH_RCDEBUG_BLUE std::cerr << "[34m"
00040 #define SH_RCDEBUG_NORMAL std::cerr << "[0m"
00041
00042 #endif
00043
00044 namespace SH {
00045
00050 class
00051 SH_DLLEXPORT
00052 ShRefCountable
00053 {
00054 public:
00055 ShRefCountable()
00056 : m_refCount(0)
00057 {
00058 }
00059
00060 ShRefCountable(const ShRefCountable&)
00061 : m_refCount(0)
00062
00063
00064 {
00065 }
00066
00067 ShRefCountable& operator=(const ShRefCountable&)
00068 {
00069
00070
00071 return *this;
00072 }
00073
00074 #ifdef SH_REFCOUNT_DEBUGGING
00075
00076 virtual ~ShRefCountable() {}
00077 #endif
00078
00079 int acquireRef() const
00080 {
00081 #ifdef SH_REFCOUNT_DEBUGGING
00082 SH_RCDEBUG_GREEN;
00083 std::cerr << " [+] " << std::setw(10) << this << " <" << typeid(*this).name() << ">"
00084 << ": " << m_refCount << "->" << (m_refCount + 1) << std::endl;
00085 SH_RCDEBUG_NORMAL;
00086 #endif
00087 return ++m_refCount;
00088 }
00089
00090 int releaseRef() const
00091 {
00092 #ifdef SH_REFCOUNT_DEBUGGING
00093 SH_RCDEBUG_RED;
00094 std::cerr << " [-] " << std::setw(10) << this << " <" << typeid(*this).name() << ">"
00095 << ": " << m_refCount << "->" << (m_refCount - 1) << std::endl;
00096 SH_RCDEBUG_NORMAL;
00097 #endif
00098 return --m_refCount;
00099 }
00100
00101 int refCount() const
00102 {
00103 return m_refCount;
00104 }
00105
00106 private:
00107 mutable int m_refCount;
00108 };
00109
00112 template<typename T>
00113 class ShPointer
00114 {
00115 public:
00116 ShPointer();
00117 ShPointer(T* object);
00118 ShPointer(const ShPointer& other);
00119 template<typename S>
00120 ShPointer(const ShPointer<S>& other);
00121
00122 ~ShPointer();
00123
00124 ShPointer& operator=(T* other);
00125 ShPointer& operator=(const ShPointer& other);
00126 template<typename S>
00127 ShPointer& operator=(const ShPointer<S>& other);
00128
00130 bool operator==(const ShPointer& other) const;
00131
00133 bool operator!=(const ShPointer& other) const;
00134
00136 bool operator<(const ShPointer& other) const;
00137
00138 T& operator*() const;
00139 T* operator->() const;
00140
00143 operator bool() const;
00144
00146 int refCount() const;
00147
00149 T* object() const;
00150
00151 void swap(ShPointer& other);
00152
00153 private:
00154 void releaseRef();
00155
00156 T* m_object;
00157 };
00158
00159 template<typename T, typename S>
00160 ShPointer<T> shref_static_cast(const ShPointer<S>& other);
00161
00162 template<typename T, typename S>
00163 ShPointer<T> shref_dynamic_cast(const ShPointer<S>& other);
00164
00165 template<typename T, typename S>
00166 ShPointer<T> shref_const_cast(const ShPointer<S>& other);
00167
00168 }
00169
00170 #include "ShRefCountImpl.hpp"
00171
00172 #endif