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