00001 ////////////////////////////////////////////////////////////////////// 00002 // Copyright (c) 2001-2002 David Pritchard <drpritch@alumni.uwaterloo.ca> 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License 00006 // as published by the Free Software Foundation; either 00007 // version 2 of the License, or (at your option) any later 00008 // version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 00019 #ifndef freecloth_resmgt_rcShdPtr_h 00020 #define freecloth_resmgt_rcShdPtr_h 00021 00022 #ifndef freecloth_base_typeinfo 00023 #include <freecloth/base/typeinfo> 00024 #endif 00025 00026 #ifndef freecloth_resmgt_package_h 00027 #include <freecloth/resmgt/package.h> 00028 #endif 00029 00030 FREECLOTH_NAMESPACE_START 00031 00032 //////////////////////////////////////////////////////////////////////////////// 00033 // FORWARD DECLARATIONS 00034 00035 template <class T> 00036 class RCShdPtr; 00037 00038 class RCBase; 00039 00040 //////////////////////////////////////////////////////////////////////////////// 00041 /*! 00042 * \class RCShdPtrBase freecloth/resmgt/rcShdPtr.h 00043 * \brief Base class for reference counted smart pointer. 00044 * 00045 * This is not intended for general use. Use RCShdPtr. 00046 */ 00047 class RCShdPtrBase 00048 { 00049 public: 00050 //----- member functions ----- 00051 bool operator==( const RCBase* ) const; 00052 bool operator!=( const RCBase* ) const; 00053 00054 protected: 00055 //----- member functions ----- 00056 RCShdPtrBase(); 00057 00058 void acquire( RCBase* ); 00059 void release(); 00060 00061 //----- data members ----- 00062 RCBase* _ptr; 00063 }; 00064 00065 //////////////////////////////////////////////////////////////////////////////// 00066 // GLOBAL FUNCTIONS 00067 // 00068 bool operator==( const RCBase*, const RCShdPtrBase& ); 00069 bool operator!=( const RCBase*, const RCShdPtrBase& ); 00070 00071 00072 //////////////////////////////////////////////////////////////////////////////// 00073 /*! 00074 * \class RCShdPtr freecloth/resmgt/rcShdPtr.h 00075 * \brief Reference-counted shared smart pointer. 00076 * 00077 * This is a general-purpose smart pointer class. It takes ownership of the 00078 * input pointer on construction, and deletes the input pointer when its 00079 * reference count drops to zero. 00080 * 00081 * The reference count is incremented every time RCShdPtr's copy constructor 00082 * is called. The count is decremented every time RCShdPtr's destructor is 00083 * called. Copies of this object will point to the same data, hence "shared" 00084 * smart pointer; this is not a copy-on-write pointer. 00085 * 00086 * The template parameter must be derived from RCBase. At present, it should 00087 * not be of const type. 00088 */ 00089 00090 // FIXME: separate into RCBase<> and RCProxy<> style for more allocation 00091 // efficiency (a la discreet) 00092 // FIXME: need to support const 00093 // 00094 // Modelled on Yonat Sharon's code. 00095 // 00096 template <class T> 00097 class RCShdPtr : public RCShdPtrBase 00098 { 00099 public: 00100 //----- types and enumerations ----- 00101 typedef T element_type; 00102 00103 //----- member functions ----- 00104 explicit RCShdPtr( T* = 0 ); 00105 // Copy constructor. Both rhs and this will point to the same data. 00106 RCShdPtr( const RCShdPtr& rhs ); 00107 ~RCShdPtr(); 00108 00109 RCShdPtr& operator=( const RCShdPtr& rhs ); 00110 00111 #ifdef HAVE_MEMBER_TEMPLATES 00112 //template <class X> friend class RCShdPtr<X>; 00113 template <class X> 00114 RCShdPtr( const RCShdPtr<X>& rhs ) 00115 { 00116 // verify that X* can be converted to T* (i.e. X* is const T*, or 00117 // T is a base class of X) 00118 X* x; 00119 T* t = x; 00120 00121 acquire( rhs.get() ); 00122 } 00123 00124 template <class X> 00125 RCShdPtr& operator=( const RCShdPtr<X>& rhs ) 00126 { 00127 // verify that X* can be converted to T* (i.e. X* is const T*, or 00128 // T is a base class of X) 00129 X* x; 00130 T* t = x; 00131 if ( rhs.get() != _ptr ) { 00132 release(); 00133 acquire( rhs.get() ); 00134 } 00135 return *this; 00136 } 00137 template <class X> 00138 bool operator==( const RCShdPtr<X>& rhs ) const 00139 { 00140 return _ptr == static_cast<RCBase*>( rhs.get() ); 00141 } 00142 template <class X> 00143 bool operator!=( const RCShdPtr<X>& rhs ) const 00144 { 00145 return _ptr != static_cast<RCBase*>( rhs.get() ); 00146 } 00147 #endif 00148 00149 bool isNull() const; 00150 T& operator* () const; 00151 T* operator-> () const; 00152 T* get() const; 00153 bool operator== ( const RCShdPtr& ) const; 00154 bool operator!= ( const RCShdPtr& ) const; 00155 bool operator== ( const RCBase* ) const; 00156 bool operator!= ( const RCBase* ) const; 00157 00158 private: 00159 }; 00160 00161 //////////////////////////////////////////////////////////////////////////////// 00162 // GLOBAL FUNCTIONS 00163 // 00164 00165 template <class T> 00166 std::ostream& operator<<( std::ostream&, const RCShdPtr<T>& ); 00167 00168 FREECLOTH_NAMESPACE_END 00169 00170 #include <freecloth/resmgt/rcShdPtr.inline.h> 00171 00172 #endif