00001 #ifndef _GEMFIRE_SHAREDPTR_HPP_
00002 #define _GEMFIRE_SHAREDPTR_HPP_
00003
00004
00005
00006
00007
00008
00009
00010 #include "SharedBase.hpp"
00011 #include "Assert.hpp"
00012 #include "TypeHelper.hpp"
00013 #include <typeinfo>
00014
00018 namespace gemfire {
00019
00022 class CPPCACHE_EXPORT SPEHelper
00023 {
00024 public:
00025
00026 static void throwNullPointerException( const char* ename );
00027
00028 static void throwClassCastException( const char* msg,
00029 const char* fromType, const char* toType );
00030 };
00031
00032 #if GF_DEVEL_ASSERTS == 1
00033 #define GF_CHECK_NPE(x) if ( x != NULL ) { } else gemfire::SPEHelper::throwNullPointerException( typeid( *this ).name() )
00034 #else
00035 #define GF_CHECK_NPE(x)
00036 #endif
00037
00038 template<class Target>
00041 class SharedPtr {
00042
00043 public:
00045 typedef Target* rawPtrType;
00046
00048 inline SharedPtr()
00049 : m_ptr(NULL)
00050 {}
00051
00053 inline SharedPtr(const Target* ptr)
00054 : m_ptr(const_cast<Target *>(ptr))
00055 {
00056 if (NULL != m_ptr)
00057 m_ptr->preserveSB();
00058 }
00059
00061 inline SharedPtr(const SharedPtr& other)
00062 : m_ptr(other.m_ptr)
00063 {
00064 if (NULL != m_ptr)
00065 m_ptr->preserveSB();
00066 }
00067
00068 template<class Other>
00070 inline SharedPtr(const SharedPtr<Other>& other)
00071 : m_ptr(other.ptr())
00072 {
00073 if (NULL != m_ptr)
00074 m_ptr->preserveSB();
00075 }
00076
00078 inline ~SharedPtr()
00079 {
00080 if (NULL != m_ptr)
00081 m_ptr->releaseSB();
00082
00083 m_ptr = NULL;
00084 }
00085
00086 inline Target* operator -> () const
00087 {
00088 GF_CHECK_NPE( m_ptr );
00089 GF_DEV_ASSERT( m_ptr->refCount( ) > 0 );
00090
00091 return m_ptr;
00092 }
00093
00094 inline Target& operator * () const
00095 {
00096 GF_CHECK_NPE( m_ptr );
00097 return *m_ptr;
00098 }
00099
00100 inline SharedPtr& operator = (Target * other)
00101 {
00102 if (NULL != other)
00103 other->preserveSB();
00104
00105 if (NULL != m_ptr)
00106 m_ptr->releaseSB();
00107
00108 m_ptr = other;
00109
00110 return *this;
00111 }
00112
00113 inline SharedPtr& operator = (const SharedPtr& other)
00114 {
00115 Target* otherPtr = other.m_ptr;
00116
00117 if ( NULL != otherPtr ) {
00118 otherPtr->preserveSB( );
00119 }
00120 if ( NULL != m_ptr ) {
00121 m_ptr->releaseSB( );
00122 }
00123 m_ptr = otherPtr;
00124
00125 GF_DEV_ASSERT( otherPtr == other.m_ptr );
00126
00127 return *this;
00128 }
00129
00130 template<class Other>
00131 inline SharedPtr& operator = (const SharedPtr<Other>& other)
00132 {
00133 Other* otherPtr = other.ptr( );
00134
00135 if ( NULL != otherPtr ) {
00136 otherPtr->preserveSB( );
00137 }
00138 if ( NULL != m_ptr ) {
00139 m_ptr->releaseSB( );
00140 }
00141 m_ptr = otherPtr;
00142
00143 GF_DEV_ASSERT( otherPtr == other.ptr( ) );
00144
00145 return *this;
00146 }
00147
00148 template<class Other>
00149 inline SharedPtr& operator = (Other* other)
00150 {
00151 if ( NULL != other ) {
00152 other->preserveSB( );
00153 }
00154 if ( NULL != m_ptr ) {
00155 m_ptr->releaseSB( );
00156 }
00157 m_ptr = other;
00158
00159 return *this;
00160 }
00161
00162 template<class Other>
00163 inline SharedPtr& operator = (const Other* other)
00164 {
00165 if ( NULL != other ) {
00166 other->preserveSB( );
00167 }
00168 if ( NULL != m_ptr ) {
00169 m_ptr->releaseSB( );
00170 }
00171 m_ptr = other;
00172
00173 return *this;
00174 }
00175
00176 inline Bool operator == (const Target* other) const
00177 { return m_ptr == other; }
00178
00179 inline Bool operator != (const Target* other) const
00180 { return m_ptr != other; }
00181
00182 inline Bool operator == (const SharedPtr& other) const
00183 { return m_ptr == other.m_ptr; }
00184
00185 inline Bool operator != (const SharedPtr& other) const
00186 { return m_ptr != other.m_ptr; }
00187
00188 template<class Other>
00189 inline Bool operator == (const SharedPtr<Other>& other)
00190 {
00191 return ((const void*)m_ptr) == ((const void*) other.ptr() );
00192 }
00193
00194 template<class Other>
00195 inline Bool operator != (const SharedPtr<Other>& other)
00196 { return ! operator == (other); }
00197
00198 inline Target* ptr() const
00199 {
00200 return m_ptr;
00201 }
00202
00203
00204 private:
00205
00206 Target* m_ptr;
00207
00208 };
00209
00210 typedef SharedPtr<SharedBase> SharedBasePtr;
00211
00212
00224 template <class TargetSP, class Other>
00225 TargetSP staticCast( const SharedPtr<Other>& other )
00226 {
00227 GF_D_ASSERT( ( other.ptr( ) == NULL ) ||
00228 ( dynamic_cast<GF_UNWRAP_SP( TargetSP )*>( other.ptr( ) ) != NULL ) );
00229
00230 return TargetSP( static_cast<GF_UNWRAP_SP( TargetSP )*>( other.ptr( ) ) );
00231 }
00232
00236 template <class TargetSP, class Other>
00237 TargetSP dynCast( const SharedPtr<Other>& other )
00238 {
00239 GF_UNWRAP_SP( TargetSP )* otherPtr;
00240
00241 if ( ( other.ptr( ) == NULL ) ) {
00242 return NULL;
00243 } else if ( ( otherPtr = dynamic_cast<GF_UNWRAP_SP( TargetSP )*>
00244 ( other.ptr( ) ) ) != NULL ) {
00245 return TargetSP( otherPtr );
00246 } else {
00247 SPEHelper::throwClassCastException( "dynCast: cast failed",
00248 typeid( other ).name( ), typeid( TargetSP ).name( ) );
00249 return NULL;
00250 }
00251 }
00252
00253 }
00254
00255 #endif
00256