ShRefCount.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright 2003-2005 Serious Hack Inc.
00004 // 
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library 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 GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00018 // MA  02110-1301, USA
00020 #ifndef SHREFCOUNT_HPP
00021 #define SHREFCOUNT_HPP
00022 
00023 #include <utility>
00024 #include "ShDllExport.hpp"
00025 
00026 // #define SH_REFCOUNT_DEBUGGING
00027 
00028 #ifdef SH_REFCOUNT_DEBUGGING
00029 #include <iostream>
00030 #include <iomanip>
00031 #include "ShDebug.hpp"
00032 
00033 #define SH_RCDEBUG_GREEN std::cerr << ""
00034 #define SH_RCDEBUG_RED std::cerr << ""
00035 #define SH_RCDEBUG_BLUE std::cerr << ""
00036 #define SH_RCDEBUG_NORMAL std::cerr << ""
00037 
00038 #endif
00039 
00040 namespace SH {
00041 
00046 class 
00047 SH_DLLEXPORT
00048 ShRefCountable 
00049 {
00050 public:
00051   ShRefCountable()
00052     : m_refCount(0)
00053   {
00054   }
00055 
00056   ShRefCountable(const ShRefCountable&)
00057     : m_refCount(0)
00058     // any new RefCountable should have a zero refcount, even if it's
00059     // made as a copy
00060   {
00061   }
00062 
00063   ShRefCountable& operator=(const ShRefCountable&)
00064   {
00065     // we don't actually change refCount here
00066     // this is indeed the intended behaviour
00067     return *this;
00068   }
00069 
00070 #ifdef SH_REFCOUNT_DEBUGGING
00071   // Just to make this polymorphic, so typeid() works as expected
00072   virtual ~ShRefCountable() {}   
00073 #endif
00074   
00075   int acquireRef() const
00076   {
00077 #ifdef SH_REFCOUNT_DEBUGGING
00078     SH_RCDEBUG_GREEN;
00079     std::cerr << "   [+] " << std::setw(10) << this << " <" << typeid(*this).name() << ">"
00080               << ": " << m_refCount << "->" << (m_refCount + 1) << std::endl;
00081     SH_RCDEBUG_NORMAL;
00082 #endif
00083     return ++m_refCount;
00084   }
00085   
00086   int releaseRef() const
00087   {
00088 #ifdef SH_REFCOUNT_DEBUGGING
00089     SH_RCDEBUG_RED;
00090     std::cerr << "   [-] " << std::setw(10) << this << " <" << typeid(*this).name() << ">"
00091               << ": " << m_refCount << "->" << (m_refCount - 1) << std::endl;
00092     SH_RCDEBUG_NORMAL;
00093 #endif
00094     return --m_refCount;
00095   }
00096 
00097   int refCount() const
00098   {
00099     return m_refCount;
00100   }
00101 
00102 private:
00103   mutable int m_refCount;
00104 };
00105 
00108 template<typename T>
00109 class ShPointer 
00110 {
00111 public:
00112   ShPointer();
00113   ShPointer(T* object);
00114   ShPointer(const ShPointer& other);
00115   template<typename S>
00116   ShPointer(const ShPointer<S>& other);
00117   
00118   ~ShPointer();
00119 
00120   ShPointer& operator=(T* other);
00121   ShPointer& operator=(const ShPointer& other);
00122   template<typename S>
00123   ShPointer& operator=(const ShPointer<S>& other);
00124 
00126   bool operator==(const ShPointer& other) const;
00127 
00129   bool operator!=(const ShPointer& other) const;
00130 
00132   bool operator<(const ShPointer& other) const;
00133 
00134   T& operator*() const;
00135   T* operator->() const;
00136 
00137   // Idea taken from the Boost shared_ptr implementation.
00138   typedef T * (ShPointer<T>::*unspecified_bool_type)() const;
00139     
00141   operator unspecified_bool_type() const
00142   {
00143     return m_object == 0 ? 0 : &ShPointer<T>::object;
00144   }  
00145 
00147   int refCount() const;
00148 
00150   T* object() const;
00151 
00152   void swap(ShPointer& other);
00153 
00154 private:
00155   void releaseRef();
00156   
00157   T* m_object;
00158 };
00159 
00160 template<typename T, typename S>
00161 ShPointer<T> shref_static_cast(const ShPointer<S>& other);
00162 
00163 template<typename T, typename S>
00164 ShPointer<T> shref_dynamic_cast(const ShPointer<S>& other);
00165 
00166 template<typename T, typename S>
00167 ShPointer<T> shref_const_cast(const ShPointer<S>& other);
00168 
00169 } // namespace SH
00170 
00171 #include "ShRefCountImpl.hpp"
00172 
00173 #endif

Generated on Wed Nov 9 15:29:39 2005 for Sh by  doxygen 1.4.5