Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

c:/home/kevn/src/animaniac/ani/Util/smart_ptr.h

Go to the documentation of this file.
00001 
00010 // prevent multiple includes
00011 #ifndef SUBSYNTH_BOOST_SMART_PTR_H
00012 #define SUBSYNTH_BOOST_SMART_PTR_H
00013 
00014 //  Boost smart_ptr.hpp header file  -----------------------------------------//
00015 
00016 // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. Permission to copy,
00017 // use, modify, sell and distribute this software is granted provided this
00018 // copyright notice appears in all copies. This software is provided "as is"
00019 // without express or implied warranty, and with no claim as to its
00020 // suitability for any purpose.
00021 
00022 // needed includes
00023 #include <cstddef>            // for std::size_t
00024 #include <memory>             // for std::auto_ptr
00025 #include <algorithm>          // for std::swap
00026 #include <functional>         // for std::less
00027 
00029 namespace syn
00030 {
00031 
00032    template< typename T >
00033     inline void checked_delete(T * x)
00034     {
00035         delete x;
00036     }
00037 
00038     template< typename T >
00039     inline void checked_array_delete(T  * x)
00040     {
00041         delete [] x;
00042     }
00043 
00044 
00045 namespace detail {
00046 
00047 template<typename T> struct shared_deleter
00048 {
00049    static void del(T * p)
00050    {
00051       checked_delete(p);
00052    }
00053 };
00054 
00055 struct dynamic_cast_tag {};
00056 
00057 template<class T> struct shared_ptr_traits
00058 {
00059    typedef T & reference;
00060 };
00061 
00062 template<> struct shared_ptr_traits<void>
00063 {
00064    typedef void reference;
00065 };
00066 
00067 } // namespace detail
00068 // shared_ptr --------------------------------------------------------------//
00069 
00071 
00075 template<typename T> class shared_ptr {
00076   public:
00077    typedef T element_type;
00078 
00079    explicit shared_ptr(T* p =0) : px(p) {
00080       try { pn = new long(1); }  // fix: prevent leak if new throws
00081       catch (...) { delete p; throw; } 
00082    }
00083 
00084    shared_ptr(const shared_ptr& r) : px(r.px) { ++*(pn = r.pn); }  // never throws
00085 
00086    ~shared_ptr() { dispose(); }
00087 
00088    shared_ptr& operator=(const shared_ptr& r) {
00089       share(r.px,r.pn);
00090       return *this;
00091    }
00092 
00093 #if !defined( BOOST_NO_MEMBER_TEMPLATES )
00094    template<typename Y>
00095       shared_ptr(const shared_ptr<Y>& r) : px(r.px) {  // never throws 
00096          ++*(pn = r.pn); 
00097       }
00098 
00099    template<typename Y>
00100       shared_ptr(std::auto_ptr<Y>& r) { 
00101          pn = new long(1); // may throw
00102          px = r.release(); // fix: moved here to stop leak if new throws
00103       } 
00104 
00105    template<typename Y>
00106       shared_ptr& operator=(const shared_ptr<Y>& r) { 
00107          share(r.px,r.pn);
00108          return *this;
00109       }
00110 
00111    template<typename Y>
00112       shared_ptr& operator=(std::auto_ptr<Y>& r) {
00113          // code choice driven by guarantee of "no effect if new throws"
00114          if (*pn == 1) { delete px; }
00115          else { // allocate new reference counter
00116            long * tmp = new long(1); // may throw
00117            --*pn; // only decrement once danger of new throwing is past
00118            pn = tmp;
00119          } // allocate new reference counter
00120          px = r.release(); // fix: moved here so doesn't leak if new throws 
00121          return *this;
00122       }
00123 #else
00124       shared_ptr(std::auto_ptr<T>& r) { 
00125          pn = new long(1); // may throw
00126          px = r.release(); // fix: moved here to stop leak if new throws
00127       } 
00128 
00129       shared_ptr& operator=(std::auto_ptr<T>& r) {
00130          // code choice driven by guarantee of "no effect if new throws"
00131          if (*pn == 1) { delete px; }
00132          else { // allocate new reference counter
00133            long * tmp = new long(1); // may throw
00134            --*pn; // only decrement once danger of new throwing is past
00135            pn = tmp;
00136          } // allocate new reference counter
00137          px = r.release(); // fix: moved here so doesn't leak if new throws 
00138          return *this;
00139       }
00140 #endif
00141 
00142    void reset(T* p=0) {
00143       if ( px == p ) return;  // fix: self-assignment safe
00144       if (--*pn == 0) { delete px; }
00145       else { // allocate new reference counter
00146         try { pn = new long; }  // fix: prevent leak if new throws
00147         catch (...) {
00148           ++*pn;  // undo effect of --*pn above to meet effects guarantee 
00149           delete p;
00150           throw;
00151         } // catch
00152       } // allocate new reference counter
00153       *pn = 1;
00154       px = p;
00155    } // reset
00156 
00157    T& operator*() const          { return *px; }  // never throws
00158    T* operator->() const         { return px; }  // never throws
00159    T* get() const                { return px; }  // never throws
00160  #ifdef BOOST_SMART_PTR_CONVERSION
00161    // get() is safer! Define BOOST_SMART_PTR_CONVERSION at your own risk!
00162    operator T*() const           { return px; }  // never throws 
00163  #endif
00164 
00165    long use_count() const        { return *pn; }  // never throws
00166    bool unique() const           { return *pn == 1; }  // never throws
00167 
00168    void swap(shared_ptr<T>& other)  // never throws
00169      { std::swap(px,other.px); std::swap(pn,other.pn); }
00170 
00171 // Tasteless as this may seem, making all members public allows member templates
00172 // to work in the absence of member template friends. (Matthew Langston)
00173 // Don't split this line into two; that causes problems for some GCC 2.95.2 builds
00174 #if defined(BOOST_NO_MEMBER_TEMPLATES) || !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
00175    private:
00176 #endif
00177 
00178    T*     px;     // contained pointer
00179    long*  pn;     // ptr to reference counter
00180 
00181 // Don't split this line into two; that causes problems for some GCC 2.95.2 builds
00182 #if !defined( BOOST_NO_MEMBER_TEMPLATES ) && !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
00183    template<typename Y> friend class shared_ptr;
00184 #endif
00185 
00186    void dispose() { if (--*pn == 0) { delete px; delete pn; } }
00187 
00188    void share(T* rpx, long* rpn) {
00189       if (pn != rpn) {
00190          dispose();
00191          px = rpx;
00192          ++*(pn = rpn);
00193       }
00194    } // share
00195 };  // shared_ptr
00196 
00197 template<typename T, typename U>
00198   inline bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b)
00199     { return a.get() == b.get(); }
00200 
00201 template<typename T, typename U>
00202   inline bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b)
00203     { return a.get() != b.get(); }
00204 /*
00205 template<class _K, class _Pr, class _A> inline
00206    bool operator!=(const set<_K, _Pr, _A>& _X,
00207       const set<_K, _Pr, _A>& _Y)
00208    {return (!(_X == _Y)); }
00209 */
00210 
00211 template<typename T, typename U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
00212 {
00213    return shared_ptr<T>(r, detail::dynamic_cast_tag());
00214 }
00215 
00216 } // namespace syn
00217 
00218 #endif

Generated on Wed Jun 12 01:54:02 2002 for Animaniac by doxygen1.2.15