fei_SharedPtr.hpp

00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2005 Sandia Corporation.                              */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 #ifndef _fei_SharedPtr_hpp_
00010 #define _fei_SharedPtr_hpp_
00011 
00012 #include <fei_macros.hpp>
00013 //
00014 //fei::SharedPtr is a copy of the Sierra system's SharedPtr class, which
00015 //was added by Kevin Copps. This class is a close copy of the boost shared_ptr.
00016 //
00017 //NOTE: In this copy, I've removed the member function 'swap', and the 
00018 //std::less specialization.
00019 //
00020 //boost::shared_ptr now allows a second template parameter which specifies
00021 //a deleter object. Instead of adopting that, I'm taking a lazy approach and
00022 //simply adding a default bool argument to a constructor which specifies 
00023 //whether the SharedPtr should delete the pointer or not.
00024 //
00025 
00026 // #ifdef SIERRA_NO_MEMBER_TEMPLATES
00027 // #define FEI_NO_MEMBER_TEMPLATES
00028 // #endif
00029 
00030 namespace fei {
00031 
00065 template<typename T> class SharedPtr { 
00066  
00067   public: 
00068  
00072     typedef T element_type; 
00073  
00084     explicit SharedPtr(T* p) 
00085       : pointer(p)
00086       {
00087   try { // prevent leak if new throws 
00088     count = new long(1); 
00089   } catch (...) {
00090     delete p;
00091     throw;
00092   }
00093       }
00094  
00095     SharedPtr(void) 
00096       : pointer(0) {
00097         count = new long(1); 
00098     } 
00099 
00100 
00109    ~SharedPtr() { dispose(); } 
00110  
00111 #if !defined( FEI_NO_MEMBER_TEMPLATES ) 
00112 
00121   template<typename Y> 
00122      SharedPtr(const SharedPtr<Y>& x)
00123     : pointer(x.pointer)
00124     { 
00125       ++*(count = x.count);
00126     } 
00127  
00144   template<typename Y> 
00145     SharedPtr& operator=(const SharedPtr<Y>& x) {  
00146         share(x.pointer,x.count);
00147         return *this; 
00148     } 
00149 #endif // FEI_NO_MEMBER_TEMPLATES 
00150  
00160   SharedPtr(const SharedPtr& x) 
00161     : pointer(x.pointer)
00162     {
00163       ++*(count = x.count);
00164     }
00165  
00181   SharedPtr& operator=(const SharedPtr& x) { 
00182     share(x.pointer, x.count);
00183     return *this; 
00184   } 
00185  
00203   void reset(T* p=0) {
00204     if ( pointer == p ) return;
00205     if (--*count == 0) { 
00206       delete pointer;
00207     } 
00208     else { // allocate new reference counter
00209       try { 
00210   count = new long; 
00211       } 
00212       catch (...) { 
00213   ++*count; 
00214   delete p; 
00215   throw; 
00216       }
00217     }
00218     *count = 1;
00219     pointer = p; 
00220   } 
00221  
00228   T& operator*() const          { return *pointer; } 
00229  
00235   T* operator->() const         { return pointer; } 
00236  
00242   T* get() const                { return pointer; } 
00243  
00250   long use_count() const        { return *count; } 
00251  
00258   bool unique() const           { return *count == 1; } 
00259  
00261   void share(T* xpointer, long* xcount) { 
00262     if (count != xcount) { 
00263       ++*xcount; 
00264       dispose(); 
00265       pointer = xpointer; 
00266       count = xcount; 
00267     } 
00268   } 
00269  
00271   void dispose() { 
00272     if (--*count == 0) { 
00273       delete pointer; 
00274       delete count; 
00275     } 
00276   } 
00277  
00278   // Making all members public allows member templates 
00279   // to work in the absence of member template friends. 
00280 #if defined( FEI_NO_MEMBER_TEMPLATES ) || !defined( FEI_NO_MEMBER_TEMPLATES ) 
00281    private: 
00282 #endif 
00283  
00284    T*     pointer; // contained pointer 
00285    long*  count;   // ptr to reference counter
00286 
00287 #if !defined( FEI_NO_MEMBER_TEMPLATES ) && !defined( FEI_NO_MEMBER_TEMPLATES ) 
00288    template<typename Y> friend class SharedPtr; 
00289 #endif 
00290  
00291 };  // end class SharedPtr 
00292  
00296 template<typename T, typename U> 
00297   inline bool operator==(const SharedPtr<T>& a, const SharedPtr<U>& b) 
00298     { return a.get() == b.get(); } 
00299  
00303 template<typename T, typename U> 
00304   inline bool operator!=(const SharedPtr<T>& a, const SharedPtr<U>& b) 
00305     { return a.get() != b.get(); } 
00306 
00307 } // namespace fei
00308 
00309 #endif // _fei_SharedPtr_hpp_
00310 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends
Generated on Wed Apr 13 10:08:24 2011 for FEI by  doxygen 1.6.3