00001 #ifndef _GEMFIRE_SHAREDPTR_HPP_
00002 #define _GEMFIRE_SHAREDPTR_HPP_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "SharedBase.hpp"
00013 #include "Assert.hpp"
00014 #include "TypeHelper.hpp"
00015 #include <typeinfo>
00016 #include "SharedPtrHelper.hpp"
00017
00021 namespace gemfire {
00022
00023 #if GF_DEVEL_ASSERTS == 1
00024 #define GF_CHECK_NPE(x) if ( x != NULL ) { } else gemfire::SPEHelper::throwNullPointerException( typeid( *this ).name() )
00025 #else
00026 #define GF_CHECK_NPE(x)
00027 #endif
00028
00029 class MapEntry;
00030 class MapEntryImpl;
00031
00032 template<class Target>
00035 class SharedPtr
00036 {
00037
00038 public:
00040 inline SharedPtr()
00041 : m_ptr(NULL)
00042 {}
00043
00045 inline SharedPtr(const NullSharedBase* ptr)
00046 : m_ptr(NULL)
00047 {}
00048
00052 inline explicit SharedPtr(const Target* ptr)
00053 : m_ptr(const_cast<Target *>(ptr))
00054 {
00055 if (NULL != m_ptr)
00056 getSB( m_ptr )->preserveSB();
00057 }
00058
00060 inline SharedPtr(const SharedPtr& other)
00061 : m_ptr(other.m_ptr)
00062 {
00063 if (NULL != m_ptr)
00064 getSB( m_ptr )->preserveSB();
00065 }
00066
00070 template<class Other>
00071 inline SharedPtr(const SharedPtr<Other>& other)
00072 : m_ptr( getTarget< Target >( other.ptr( ) ) )
00073 {
00074 if (NULL != m_ptr)
00075 getSB( m_ptr )->preserveSB();
00076 }
00077
00079 inline ~SharedPtr()
00080 {
00081 if (NULL != m_ptr)
00082 getSB( m_ptr )->releaseSB();
00083
00084 m_ptr = NULL;
00085 }
00086
00087 inline Target* operator -> () const
00088 {
00089 GF_CHECK_NPE( m_ptr );
00090 GF_DEV_ASSERT( getSB( m_ptr )->refCount( ) > 0 );
00091
00092 return m_ptr;
00093 }
00094
00095 inline Target& operator * () const
00096 {
00097 GF_CHECK_NPE( m_ptr );
00098 return *m_ptr;
00099 }
00100
00104 inline SharedPtr& operator = (Target * other)
00105 {
00106 if (NULL != other)
00107 getSB( other )->preserveSB();
00108
00109 if (NULL != m_ptr)
00110 getSB( m_ptr )->releaseSB();
00111
00112 m_ptr = other;
00113
00114 return *this;
00115 }
00116
00117 inline SharedPtr& operator = (const SharedPtr& other)
00118 {
00119 Target* otherPtr = other.m_ptr;
00120
00121 if ( NULL != otherPtr ) {
00122 getSB( otherPtr )->preserveSB( );
00123 }
00124 if ( NULL != m_ptr ) {
00125 getSB( m_ptr )->releaseSB( );
00126 }
00127 m_ptr = otherPtr;
00128
00129 GF_DEV_ASSERT( otherPtr == other.m_ptr );
00130
00131 return *this;
00132 }
00133
00137 template<class Other>
00138 inline SharedPtr& operator = (const SharedPtr<Other>& other)
00139 {
00140 Other* otherPtr = other.ptr( );
00141
00142 Target* otherTargetPtr = getTarget< Target >( otherPtr );
00143
00144 if ( NULL != otherPtr ) {
00145 getSB( otherPtr )->preserveSB( );
00146 }
00147 if ( NULL != m_ptr ) {
00148 getSB( m_ptr )->releaseSB( );
00149 }
00150 m_ptr = otherTargetPtr;
00151
00152 GF_DEV_ASSERT( otherPtr == other.ptr( ) );
00153
00154 return *this;
00155 }
00156
00157 inline SharedPtr& operator = (const NullSharedBase* nullOther)
00158 {
00159 if (m_ptr != NULL) {
00160 getSB( m_ptr )->releaseSB();
00161 }
00162 m_ptr = NULL;
00163 return *this;
00164 }
00165
00170 template<class Other>
00171 inline SharedPtr& operator = (Other* other)
00172 {
00173 Target* otherTargetPtr = getTarget< Target >( other );
00174
00175 if ( NULL != other ) {
00176 getSB( other )->preserveSB( );
00177 }
00178 if ( NULL != m_ptr ) {
00179 getSB( m_ptr )->releaseSB( );
00180 }
00181 m_ptr = otherTargetPtr;
00182
00183 return *this;
00184 }
00185
00186 inline bool operator == (const Target* other) const
00187 { return m_ptr == other; }
00188
00189 inline bool operator != (const Target* other) const
00190 { return m_ptr != other; }
00191
00192 inline bool operator == (const NullSharedBase* nullOther) const
00193 { return m_ptr == NULL; }
00194
00195 inline bool operator != (const NullSharedBase* nullOther) const
00196 { return m_ptr != NULL; }
00197
00198 inline bool operator == (const SharedPtr& other) const
00199 { return m_ptr == other.m_ptr; }
00200
00201 inline bool operator != (const SharedPtr& other) const
00202 { return m_ptr != other.m_ptr; }
00203
00204 template<class Other>
00205 inline bool operator == (const SharedPtr<Other>& other)
00206 {
00207 return ((const void*)m_ptr) == ((const void*) other.ptr() );
00208 }
00209
00210 template<class Other>
00211 inline bool operator != (const SharedPtr<Other>& other)
00212 { return ! operator == (other); }
00213
00214 inline Target* ptr() const
00215 {
00216 return m_ptr;
00217 }
00218
00219
00220 private:
00221
00223 inline explicit SharedPtr(bool noInit)
00224 {}
00225
00226 Target* m_ptr;
00227
00228 friend class MapEntry;
00229 friend class MapEntryImpl;
00230
00231 };
00232
00233 typedef SharedPtr<SharedBase> SharedBasePtr;
00234
00235
00247 template <class TargetSP, class Other>
00248 TargetSP staticCast( const SharedPtr<Other>& other )
00249 {
00250 GF_D_ASSERT( ( other.ptr( ) == NULL ) ||
00251 ( dynamic_cast<GF_UNWRAP_SP( TargetSP )*>( other.ptr( ) ) != NULL ) );
00252
00253 return TargetSP( static_cast<GF_UNWRAP_SP( TargetSP )*>( other.ptr( ) ) );
00254 }
00255
00259 template <class TargetSP, class Other>
00260 TargetSP dynCast( const SharedPtr<Other>& other )
00261 {
00262 GF_UNWRAP_SP( TargetSP )* otherPtr;
00263
00264 if ( ( other.ptr( ) == NULL ) ) {
00265 return NULLPTR;
00266 } else if ( ( otherPtr = dynamic_cast<GF_UNWRAP_SP( TargetSP )*>
00267 ( other.ptr( ) ) ) != NULL ) {
00268 return TargetSP( otherPtr );
00269 } else {
00270 SPEHelper::throwClassCastException( "dynCast: cast failed",
00271 typeid( other ).name( ), typeid( TargetSP ).name( ) );
00272 return NULLPTR;
00273 }
00274 }
00275
00279 template<class TargetSP, class Other>
00280 bool instanceOf(const SharedPtr<Other>& other)
00281 {
00282 return (dynamic_cast<GF_UNWRAP_SP(TargetSP)*> (other.ptr()) != NULL);
00283 }
00284
00285 }
00286
00287 #endif