FEI Version of the Day
fei_SharedPtr.hpp
00001 /*
00002 // @HEADER
00003 // ************************************************************************
00004 //             FEI: Finite Element Interface to Linear Solvers
00005 //                  Copyright (2005) Sandia Corporation.
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the
00008 // U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Alan Williams (william@sandia.gov) 
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 */
00042 
00043 
00044 #ifndef _fei_SharedPtr_hpp_
00045 #define _fei_SharedPtr_hpp_
00046 
00047 #include <fei_macros.hpp>
00048 //
00049 //fei::SharedPtr is a copy of the Sierra system's SharedPtr class, which
00050 //was added by Kevin Copps. This class is a close copy of the boost shared_ptr.
00051 //
00052 //NOTE: In this copy, I've removed the member function 'swap', and the 
00053 //std::less specialization.
00054 //
00055 //boost::shared_ptr now allows a second template parameter which specifies
00056 //a deleter object. Instead of adopting that, I'm taking a lazy approach and
00057 //simply adding a default bool argument to a constructor which specifies 
00058 //whether the SharedPtr should delete the pointer or not.
00059 //
00060 
00061 // #ifdef SIERRA_NO_MEMBER_TEMPLATES
00062 // #define FEI_NO_MEMBER_TEMPLATES
00063 // #endif
00064 
00065 namespace fei {
00066 
00100 template<typename T> class SharedPtr { 
00101  
00102   public: 
00103  
00107     typedef T element_type; 
00108  
00119     explicit SharedPtr(T* p) 
00120       : pointer(p)
00121       {
00122   try { // prevent leak if new throws 
00123     count = new long(1); 
00124   } catch (...) {
00125     delete p;
00126     throw;
00127   }
00128       }
00129  
00130     SharedPtr(void) 
00131       : pointer(0) {
00132         count = new long(1); 
00133     } 
00134 
00135 
00144    ~SharedPtr() { dispose(); } 
00145  
00146 #if !defined( FEI_NO_MEMBER_TEMPLATES ) 
00147 
00156   template<typename Y> 
00157      SharedPtr(const SharedPtr<Y>& x)
00158     : pointer(x.pointer)
00159     { 
00160       ++*(count = x.count);
00161     } 
00162  
00179   template<typename Y> 
00180     SharedPtr& operator=(const SharedPtr<Y>& x) {  
00181         share(x.pointer,x.count);
00182         return *this; 
00183     } 
00184 #endif // FEI_NO_MEMBER_TEMPLATES 
00185  
00195   SharedPtr(const SharedPtr& x) 
00196     : pointer(x.pointer)
00197     {
00198       ++*(count = x.count);
00199     }
00200  
00216   SharedPtr& operator=(const SharedPtr& x) { 
00217     share(x.pointer, x.count);
00218     return *this; 
00219   } 
00220  
00238   void reset(T* p=0) {
00239     if ( pointer == p ) return;
00240     if (--*count == 0) { 
00241       delete pointer;
00242     } 
00243     else { // allocate new reference counter
00244       try { 
00245   count = new long; 
00246       } 
00247       catch (...) { 
00248   ++*count; 
00249   delete p; 
00250   throw; 
00251       }
00252     }
00253     *count = 1;
00254     pointer = p; 
00255   } 
00256  
00263   T& operator*() const          { return *pointer; } 
00264  
00270   T* operator->() const         { return pointer; } 
00271  
00277   T* get() const                { return pointer; } 
00278  
00285   long use_count() const        { return *count; } 
00286  
00293   bool unique() const           { return *count == 1; } 
00294  
00296   void share(T* xpointer, long* xcount) { 
00297     if (count != xcount) { 
00298       ++*xcount; 
00299       dispose(); 
00300       pointer = xpointer; 
00301       count = xcount; 
00302     } 
00303   } 
00304  
00306   void dispose() { 
00307     if (--*count == 0) { 
00308       delete pointer; 
00309       delete count; 
00310     } 
00311   } 
00312  
00313   // Making all members public allows member templates 
00314   // to work in the absence of member template friends. 
00315 #if defined( FEI_NO_MEMBER_TEMPLATES ) || !defined( FEI_NO_MEMBER_TEMPLATES ) 
00316    private: 
00317 #endif 
00318  
00319    T*     pointer; // contained pointer 
00320    long*  count;   // ptr to reference counter
00321 
00322 #if !defined( FEI_NO_MEMBER_TEMPLATES ) && !defined( FEI_NO_MEMBER_TEMPLATES ) 
00323    template<typename Y> friend class SharedPtr; 
00324 #endif 
00325  
00326 };  // end class SharedPtr 
00327  
00331 template<typename T, typename U> 
00332   inline bool operator==(const SharedPtr<T>& a, const SharedPtr<U>& b) 
00333     { return a.get() == b.get(); } 
00334  
00338 template<typename T, typename U> 
00339   inline bool operator!=(const SharedPtr<T>& a, const SharedPtr<U>& b) 
00340     { return a.get() != b.get(); } 
00341 
00342 } // namespace fei
00343 
00344 #endif // _fei_SharedPtr_hpp_
00345 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends