Main Page   Class Hierarchy   Compound List   File List   Compound Members  

rcProxyShdPtr.h

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_rcProxyShdPtr_h
00020 #define freecloth_resmgt_rcProxyShdPtr_h
00021 
00022 #ifndef freecloth_resmgt_package_h
00023 #include <freecloth/resmgt/package.h>
00024 #endif
00025 
00026 #ifndef freecloth_base_typeinfo
00027 #include <freecloth/base/typeinfo>
00028 #endif
00029 
00030 FREECLOTH_NAMESPACE_START
00031 
00032 ////////////////////////////////////////////////////////////////////////////////
00033 // FORWARD DECLARATIONS
00034 
00035 template <class T>
00036 class RCProxyShdPtr;
00037 
00038 ////////////////////////////////////////////////////////////////////////////////
00039 /*!
00040  * \class RCProxyShdPtrBase freecloth/resmgt/rcProxyShdPtr.h
00041  * \brief Base class for reference counted smart pointer proxy.
00042  *
00043  * This is not intended for general use. Use RCProxyShdPtr.
00044  */
00045 class RCProxyShdPtrBase
00046 {
00047 protected:
00048     //----- classes -----
00049     class Data;
00050     //----- member functions -----
00051     RCProxyShdPtrBase();
00052 
00053 public:
00054     // FIXME: g++ doesn't like templated friends. Must use this as a
00055     // substitute for now.
00056 
00057     //----- data members -----
00058     Data*   _data;
00059 
00060 };
00061 
00062 ////////////////////////////////////////////////////////////////////////////////
00063 /*!
00064  * \class RCProxyShdPtrBase::Data freecloth/resmgt/rcProxyShdPtr.h
00065  * \brief Internal data for RCProxyShdPtrBase.
00066  */
00067 class RCProxyShdPtrBase::Data
00068 {
00069 public:
00070     //----- member functions -----
00071     Data( void* ptr = 0, UInt32 count = 1 );
00072 
00073     //----- data members -----
00074     void*   _ptr;
00075     UInt32  _count;
00076 };
00077 
00078 ////////////////////////////////////////////////////////////////////////////////
00079 /*!
00080  * \class RCProxyShdPtr freecloth/resmgt/rcProxyShdPtr.h
00081  * \brief Reference-counted shared smart pointer for non-RCBase objects.
00082  *
00083  * When using external classes, such as the STL or a commercial library,
00084  * it is not possible to change these classes to derive from RCBase, for use
00085  * with RCShdPtr. Instead, RCProxyShdPtr can be used, although it is not
00086  * quite as powerful as RCShdPtr.
00087  */
00088 
00089 // FIXME: separate into RCBase<> and RCProxy<> style for more allocation
00090 // efficiency (a la discreet)
00091 //
00092 // Modelled on Yonat Sharon's code.
00093 template <class T>
00094 class RCProxyShdPtr : public RCProxyShdPtrBase
00095 {
00096 public:
00097     //----- types and enumerations -----
00098     typedef T element_type;
00099 
00100     //----- member functions -----
00101     explicit RCProxyShdPtr( T* = 0 );
00102     RCProxyShdPtr( const RCProxyShdPtr& rhs );
00103     ~RCProxyShdPtr();
00104 
00105     RCProxyShdPtr& operator=( const RCProxyShdPtr& rhs );
00106 
00107 #ifdef HAVE_MEMBER_TEMPLATES
00108     //template <class X> friend class RCProxyShdPtr<X>;
00109     template <class X>
00110     RCProxyShdPtr( const RCProxyShdPtr<X>& rhs )
00111     {
00112         // verify that X* can be converted to T* (i.e. X* is const T*, or
00113         // T is a base class of X)
00114         X* x;
00115         T* t = x;
00116 
00117         acquire( rhs._data );
00118     }
00119 
00120     template <class X>
00121     RCProxyShdPtr& operator=( const RCProxyShdPtr<X>& rhs )
00122     {
00123         // verify that X* can be converted to T* (i.e. X* is const T*, or
00124         // T is a base class of X)
00125         X* x;
00126         T* t = x;
00127         if ( rhs._data != _data ) {
00128             release();
00129             acquire( rhs._data );
00130         }
00131         return *this;
00132     }
00133     template <class X>
00134     bool operator==( const RCProxyShdPtr<X>& rhs ) const
00135     {
00136         return _data == rhs._data;
00137     }
00138     template <class X>
00139     bool operator!=( const RCProxyShdPtr<X>& rhs ) const
00140     {
00141         return _data != rhs._data;
00142     }
00143 #endif
00144 
00145     bool isNull() const;
00146     T& operator*() const;
00147     T* operator->() const;
00148     T* get () const;
00149     bool operator==( const RCProxyShdPtr& ) const;
00150     bool operator!=( const RCProxyShdPtr& ) const;
00151 
00152 private:
00153 
00154     //----- member functions -----
00155     void acquire( Data* );
00156     void release();
00157 };
00158 
00159 ////////////////////////////////////////////////////////////////////////////////
00160 // GLOBAL FUNCTIONS
00161 //
00162 
00163 template <class T>
00164 std::ostream& operator<<( std::ostream&, const RCProxyShdPtr<T>& );
00165 
00166 FREECLOTH_NAMESPACE_END
00167 
00168 #include <freecloth/resmgt/rcProxyShdPtr.inline.h>
00169 
00170 #endif

Generated on Wed Apr 23 15:58:52 2003 for Freecloth by doxygen1.3-rc3