H:/gfcppsancout/product/include/gfcpp/SharedPtr.hpp

Go to the documentation of this file.
00001 #ifndef _GEMFIRE_SHAREDPTR_HPP_
00002 #define _GEMFIRE_SHAREDPTR_HPP_
00003 
00004 /*=========================================================================
00005  * (c) Copyright 2004-2007, GemStone Systems, Inc. All Rights Reserved.
00006  * 1260 NW Waterhouse Ave Suite 200, Beaverton OR 97006.
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 

GemFire C++ Cache API Documentation