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