boost_shared_ptr.h

00001 // <tr1/boost_shared_ptr.h> -*- C++ -*-
00002 
00003 // Copyright (C) 2005 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License along
00017 // with this library; see the file COPYING.  If not, write to the Free
00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019 // USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 //  shared_count.hpp
00031 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
00032 
00033 //  shared_ptr.hpp
00034 //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
00035 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
00036 
00037 //  weak_ptr.hpp
00038 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
00039 
00040 //  enable_shared_from_this.hpp
00041 //  Copyright (C) 2002 Peter Dimov
00042 
00043 // Distributed under the Boost Software License, Version 1.0. (See
00044 // accompanying file LICENSE_1_0.txt or copy at
00045 // http://www.boost.org/LICENSE_1_0.txt)
00046 
00047 // GCC Note:  based on version 1.32.0 of the Boost library.
00048 
00049 /** @file boost_memory.h
00050  *  This is an internal header file, included by other library headers.
00051  *  You should not attempt to use it directly.
00052  */
00053 
00054 #ifndef _BOOST_SHARED_PTR_H
00055 #define _BOOST_SHARED_PTR_H 1
00056 
00057 // namespace std::tr1
00058 namespace std
00059 {
00060 namespace tr1
00061 {
00062 
00063 class bad_weak_ptr : public std::exception
00064 {
00065 public:
00066 
00067   virtual char const* what() const throw()
00068   {
00069     return "tr1::bad_weak_ptr";
00070   }
00071 };
00072 
00073 // Helper for exception objects in <tr1/memory>
00074 // TODO this should be defined in a different file.
00075 inline void
00076 __throw_bad_weak_ptr()
00077 {
00078 #if __EXCEPTIONS
00079   throw bad_weak_ptr();
00080 #else
00081   std::abort();
00082 #endif
00083 }
00084 
00085 
00086 template <typename _Tp>
00087   struct _Sp_deleter
00088   {
00089     typedef void result_type;
00090     typedef _Tp* argument_type;
00091 
00092     void
00093     operator()(_Tp* p) const
00094     { delete p; }
00095   };
00096 
00097 
00098 class _Sp_counted_base
00099 {
00100 public:
00101 
00102   _Sp_counted_base()
00103   : _M_use_count(1), _M_weak_count(1)
00104   {
00105     // For the case of __GTHREAD_MUTEX_INIT we haven't initialised
00106     // the mutex yet, so do it now.
00107 #if defined(__GTHREADS) && defined(__GTHREAD_MUTEX_INIT)
00108     __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT;
00109     _M_mutex = __tmp;
00110 #endif
00111   }
00112 
00113   virtual
00114   ~_Sp_counted_base() // nothrow
00115   { }
00116 
00117   // dispose() is called when _M_use_count drops to zero, to release
00118   // the resources managed by *this.
00119   virtual void
00120   dispose() = 0; // nothrow
00121 
00122   // destroy() is called when _M_weak_count drops to zero.
00123   virtual void
00124   destroy() // nothrow
00125   {
00126     delete this;
00127   }
00128 
00129   virtual void*
00130   get_deleter(const std::type_info&) = 0;
00131 
00132   void
00133   add_ref_copy()
00134   {
00135     __gnu_cxx::__atomic_add(&_M_use_count, 1);
00136   }
00137 
00138   void
00139   add_ref_lock()
00140   {
00141     __gnu_cxx::lock lock(_M_mutex);
00142     if (__gnu_cxx::__exchange_and_add(&_M_use_count, 1) == 0)
00143     {
00144       _M_use_count = 0;
00145       __throw_bad_weak_ptr();
00146     }
00147   }
00148 
00149   void
00150   release() // nothrow
00151   {
00152     if (__gnu_cxx::__exchange_and_add(&_M_use_count, -1) == 1)
00153     {
00154       dispose();
00155       __glibcxx_mutex_lock(_M_mutex);
00156       __glibcxx_mutex_unlock(_M_mutex);
00157       weak_release();
00158     }
00159   }
00160 
00161   void
00162   weak_add_ref() // nothrow
00163   {
00164     __gnu_cxx::__atomic_add(&_M_weak_count, 1);
00165   }
00166 
00167   void
00168   weak_release() // nothrow
00169   {
00170     if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) == 1)
00171     {
00172       __glibcxx_mutex_lock(_M_mutex);
00173       __glibcxx_mutex_unlock(_M_mutex);
00174       destroy();
00175     }
00176   }
00177 
00178   long
00179   use_count() const // nothrow
00180   {
00181     return _M_use_count;  // XXX is this MT safe?
00182   }
00183 
00184 private:
00185 
00186   _Sp_counted_base(_Sp_counted_base const&);
00187   _Sp_counted_base& operator= (_Sp_counted_base const&);
00188 
00189   _Atomic_word _M_use_count;        // #shared
00190   _Atomic_word _M_weak_count;       // #weak + (#shared != 0)
00191   __gnu_cxx::mutex_type _M_mutex;
00192 };
00193 
00194 template <typename _Ptr, typename _Deleter>
00195 class _Sp_counted_base_impl : public _Sp_counted_base
00196 {
00197 public:
00198 
00199   /**
00200    *  @brief   
00201    *  @pre     d(p) must not throw.
00202    */
00203   _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
00204   : _M_ptr(__p), _M_del(__d)
00205   { }
00206 
00207   virtual void
00208   dispose() // nothrow
00209   {
00210     _M_del(_M_ptr);
00211   }
00212 
00213   virtual void*
00214   get_deleter(const std::type_info& __ti)
00215   {
00216     return __ti == typeid(_Deleter) ? &_M_del : 0;
00217   }
00218 
00219 private:
00220   _Sp_counted_base_impl(const _Sp_counted_base_impl&);
00221   _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
00222 
00223   _Ptr     _M_ptr; // copy constructor must not throw
00224   _Deleter _M_del; // copy constructor must not throw
00225 };
00226 
00227 class weak_count;
00228 
00229 class shared_count
00230 {
00231 private:
00232 
00233   _Sp_counted_base* _M_pi;
00234 
00235   friend class weak_count;
00236 
00237 public:
00238 
00239   shared_count()
00240   : _M_pi(0) // nothrow
00241   { }
00242 
00243   template <typename _Ptr, typename _Deleter>
00244     shared_count(_Ptr __p, _Deleter __d)
00245     : _M_pi(0)
00246     {
00247       try
00248       {
00249         _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter>(__p, __d);
00250       }
00251       catch(...)
00252       {
00253         __d(__p); // delete __p
00254         __throw_exception_again;
00255       }
00256     }
00257 
00258   // auto_ptr<_Tp> is special cased to provide the strong guarantee
00259 
00260   template <typename _Tp>
00261     explicit shared_count(std::auto_ptr<_Tp>& __r)
00262     : _M_pi(new _Sp_counted_base_impl<_Tp*,_Sp_deleter<_Tp> >(
00263             __r.get(), _Sp_deleter<_Tp>()
00264             ))
00265     { __r.release(); }
00266 
00267   // throws bad_weak_ptr when __r.use_count() == 0
00268   explicit shared_count(const weak_count& __r);
00269 
00270   ~shared_count() // nothrow
00271   {
00272     if (_M_pi != 0)
00273       _M_pi->release();
00274   }
00275 
00276   shared_count(const shared_count& __r)
00277   : _M_pi(__r._M_pi) // nothrow
00278   {
00279     if (_M_pi != 0)
00280       _M_pi->add_ref_copy();
00281   }
00282 
00283   shared_count&
00284   operator=(const shared_count& __r) // nothrow
00285   {
00286     _Sp_counted_base* __tmp = __r._M_pi;
00287 
00288     if(__tmp != _M_pi)
00289     {
00290       if(__tmp != 0)
00291         __tmp->add_ref_copy();
00292       if(_M_pi != 0)
00293         _M_pi->release();
00294       _M_pi = __tmp;
00295     }
00296     return *this;
00297   }
00298 
00299   void swap(shared_count& __r) // nothrow
00300   {
00301     _Sp_counted_base* __tmp = __r._M_pi;
00302     __r._M_pi = _M_pi;
00303     _M_pi = __tmp;
00304   }
00305 
00306   long
00307   use_count() const // nothrow
00308   { return _M_pi != 0 ? _M_pi->use_count() : 0; }
00309 
00310   bool
00311   unique() const // nothrow
00312   { return this->use_count() == 1; }
00313 
00314   friend inline bool
00315   operator==(const shared_count& __a, const shared_count& __b)
00316   { return __a._M_pi == __b._M_pi; }
00317 
00318   friend inline bool
00319   operator<(const shared_count& __a, const shared_count& __b)
00320   { return std::less<_Sp_counted_base*>()(__a._M_pi, __b._M_pi); }
00321 
00322   void*
00323   get_deleter(const std::type_info& __ti) const
00324   { return _M_pi ? _M_pi->get_deleter(__ti) : 0; }
00325 };
00326 
00327 
00328 class weak_count
00329 {
00330 private:
00331 
00332   _Sp_counted_base * _M_pi;
00333 
00334   friend class shared_count;
00335 
00336 public:
00337 
00338   weak_count()
00339   : _M_pi(0) // nothrow
00340   { }
00341 
00342   weak_count(const shared_count& __r)
00343   : _M_pi(__r._M_pi) // nothrow
00344   {
00345     if (_M_pi != 0)
00346       _M_pi->weak_add_ref();
00347   }
00348 
00349   weak_count(const weak_count& __r)
00350   : _M_pi(__r._M_pi) // nothrow
00351   {
00352     if (_M_pi != 0)
00353       _M_pi->weak_add_ref();
00354   }
00355 
00356   ~weak_count() // nothrow
00357   {
00358     if (_M_pi != 0)
00359       _M_pi->weak_release();
00360   }
00361 
00362   weak_count&
00363   operator=(const shared_count& __r) // nothrow
00364   {
00365     _Sp_counted_base* __tmp = __r._M_pi;
00366     if (__tmp != 0)
00367       __tmp->weak_add_ref();
00368     if (_M_pi != 0)
00369       _M_pi->weak_release();
00370     _M_pi = __tmp;
00371 
00372     return *this;
00373   }
00374 
00375   weak_count&
00376   operator=(const weak_count& __r) // nothrow
00377   {
00378     _Sp_counted_base * __tmp = __r._M_pi;
00379     if (__tmp != 0)
00380       __tmp->weak_add_ref();
00381     if (_M_pi != 0)
00382       _M_pi->weak_release();
00383     _M_pi = __tmp;
00384 
00385     return *this;
00386   }
00387 
00388   void
00389   swap(weak_count& __r) // nothrow
00390   {
00391     _Sp_counted_base * __tmp = __r._M_pi;
00392     __r._M_pi = _M_pi;
00393     _M_pi = __tmp;
00394   }
00395 
00396   long
00397   use_count() const // nothrow
00398   { return _M_pi != 0 ? _M_pi->use_count() : 0; }
00399 
00400   friend inline bool
00401   operator==(const weak_count& __a, const weak_count& __b)
00402   { return __a._M_pi == __b._M_pi; }
00403 
00404   friend inline bool
00405   operator<(const weak_count& __a, const weak_count& __b)
00406   { return std::less<_Sp_counted_base*>()(__a._M_pi, __b._M_pi); }
00407 };
00408 
00409 inline
00410 shared_count::shared_count(const weak_count& __r)
00411 : _M_pi(__r._M_pi)
00412 {
00413   if (_M_pi != 0)
00414   {
00415     _M_pi->add_ref_lock();
00416   }
00417   else
00418   {
00419     __throw_bad_weak_ptr();
00420   }
00421 }
00422 
00423 // fwd decls
00424 template <typename _Tp> class weak_ptr;
00425 template <typename _Tp> class enable_shared_from_this;
00426 
00427 struct __static_cast_tag {};
00428 struct __const_cast_tag {};
00429 struct __dynamic_cast_tag {};
00430 struct __polymorphic_cast_tag {};
00431 
00432 template<class _Tp> struct shared_ptr_traits
00433 {
00434     typedef _Tp & reference;
00435 };
00436 
00437 template<> struct shared_ptr_traits<void>
00438 {
00439     typedef void reference;
00440 };
00441 
00442 template<> struct shared_ptr_traits<void const>
00443 {
00444     typedef void reference;
00445 };
00446 
00447 template<> struct shared_ptr_traits<void volatile>
00448 {
00449     typedef void reference;
00450 };
00451 
00452 template<> struct shared_ptr_traits<void const volatile>
00453 {
00454     typedef void reference;
00455 };
00456 
00457 
00458 // enable_shared_from_this support
00459 
00460 // friend of enable_shared_from_this
00461 template <typename _Tp1, typename _Tp2>
00462   void
00463   __enable_shared_from_this( const shared_count& __pn,
00464                              const enable_shared_from_this<_Tp1>* __pe,
00465                              const _Tp2* __px );
00466 
00467 inline void
00468 __enable_shared_from_this(const shared_count&, ...)
00469 { }
00470 
00471 /**
00472  *  @class shared_ptr <tr1/memory>
00473  *
00474  *  A smart pointer with reference-counted copy semantics.
00475  *  The object pointed to is deleted when the last shared_ptr pointing to it
00476  *  is destroyed or reset.
00477  */
00478 
00479 template <typename _Tp>
00480   class shared_ptr
00481   {
00482     typedef typename shared_ptr_traits<_Tp>::reference _Reference;
00483 
00484   public:
00485 
00486     typedef _Tp   element_type;
00487 
00488     /** @brief  Construct an empty %shared_ptr.
00489      *  @post   use_count()==0 && get()==0
00490      */
00491     shared_ptr() : _M_ptr(0), _M_refcount() // never throws
00492     { }
00493 
00494     /** @brief  Construct a %shared_ptr that owns the pointer @a p.
00495      *  @param  p  A pointer that is convertible to element_type*.
00496      *  @post   use_count()==1 && get()==p
00497      *  @throw  std::bad_alloc, in which case @c delete @a p is called.
00498      */
00499     template <typename _Tp1>
00500       explicit shared_ptr(_Tp1* __p)
00501       : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
00502       {
00503         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00504         // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
00505 
00506         __enable_shared_from_this( _M_refcount, __p, __p );
00507       }
00508 
00509     //
00510     // Requirements: D's copy constructor and destructor must not throw
00511     //
00512     // shared_ptr will release p by calling d(p)
00513     //
00514     /** @brief  Construct a %shared_ptr that owns the pointer @a p
00515      *          and the deleter @a d.
00516      *  @param  p  A pointer.
00517      *  @param  d  A deleter.
00518      *  @post   use_count()==1 && get()==p
00519      *  @throw  std::bad_alloc, in which case @a d(p) is called.
00520      */
00521     template <typename _Tp1, typename _Deleter>
00522       shared_ptr(_Tp1* __p, _Deleter __d)
00523       : _M_ptr(__p), _M_refcount(__p, __d)
00524       {
00525         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00526         // TODO requires D is CopyConstructible and d(p) well-formed
00527 
00528         __enable_shared_from_this( _M_refcount, __p, __p );
00529       }
00530 
00531     //  generated copy constructor, assignment, destructor are fine.
00532 
00533     /** @brief  If @a r is empty, constructs an empty %shared_ptr; otherwise
00534      *          construct a %shared_ptr that shares ownership with @a r.
00535      *  @param  r  A %shared_ptr.
00536      *  @post   get()==r.get() && use_count()==r.use_count()
00537      *  @throw  std::bad_alloc, in which case 
00538      */
00539     template <typename _Tp1>
00540       shared_ptr(const shared_ptr<_Tp1>& __r)
00541       : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
00542       {
00543         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00544       }
00545 
00546     /** @brief  Constructs a %shared_ptr that shares ownership with @a r
00547      *          and stores a copy of the pointer stored in @a r.
00548      *  @param  r  A weak_ptr.
00549      *  @post   use_count()==r.use_count()
00550      *  @throw  bad_weak_ptr when r.expired(),
00551      *          in which case the constructor has no effect.
00552      */
00553     template <typename _Tp1>
00554       explicit shared_ptr(const weak_ptr<_Tp1>& __r)
00555       : _M_refcount(__r._M_refcount) // may throw
00556       {
00557         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00558         // it is now safe to copy r__._M_ptr, as _M_refcount(__r._M_refcount)
00559         // did not throw
00560         _M_ptr = __r._M_ptr;
00561       }
00562 
00563     /**
00564      * @post use_count()==1 and r.get()==0
00565      */
00566     template <typename _Tp1>
00567       explicit shared_ptr(std::auto_ptr<_Tp1>& __r)
00568       : _M_ptr(__r.get()), _M_refcount()
00569       {
00570         // TODO requires r.release() convertible to _Tp*, Tp1 is complete,
00571         // delete r.release() well-formed
00572         _Tp1 * __tmp = __r.get();
00573         _M_refcount = shared_count(__r);
00574 
00575         __enable_shared_from_this( _M_refcount, __tmp, __tmp );
00576       }
00577 
00578     template <typename _Tp1>
00579       shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
00580       : _M_ptr(static_cast<element_type*>(__r._M_ptr))
00581       , _M_refcount(__r._M_refcount)
00582       { }
00583 
00584     template <typename _Tp1>
00585       shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
00586       : _M_ptr(const_cast<element_type*>(__r._M_ptr))
00587       , _M_refcount(__r._M_refcount)
00588       { }
00589 
00590     template <typename _Tp1>
00591       shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
00592       : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr))
00593       , _M_refcount(__r._M_refcount)
00594       {
00595         if (_M_ptr == 0) // need to allocate new counter -- the cast failed
00596         {
00597           _M_refcount = shared_count();
00598         }
00599       }
00600 
00601     template <typename _Tp1>
00602       shared_ptr&
00603       operator=(const shared_ptr<_Tp1>& __r) // never throws
00604       {
00605         _M_ptr = __r._M_ptr;
00606         _M_refcount = __r._M_refcount; // shared_count::op= doesn't throw
00607         return *this;
00608       }
00609 
00610     template <typename _Tp1>
00611       shared_ptr&
00612       operator=(std::auto_ptr<_Tp1>& __r)
00613       {
00614         shared_ptr(__r).swap(*this);
00615         return *this;
00616       }
00617 
00618     void
00619     reset() // never throws
00620     { shared_ptr().swap(*this); }
00621 
00622     template <typename _Tp1>
00623       void
00624       reset(_Tp1* __p) // _Tp1 must be complete
00625       {
00626         _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); // catch self-reset errors
00627         shared_ptr(__p).swap(*this);
00628       }
00629 
00630     template <typename _Tp1, typename _Deleter>
00631       void
00632       reset(_Tp1 * __p, _Deleter __d)
00633       { shared_ptr(__p, __d).swap(*this); }
00634 
00635     // error to instantiate if _Tp is [cv-qual] void
00636     _Reference
00637     operator*() const // never throws
00638     {
00639       _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00640       return *_M_ptr;
00641     }
00642 
00643     _Tp*
00644     operator->() const // never throws
00645     {
00646       _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00647       return _M_ptr;
00648     }
00649     
00650     _Tp*
00651     get() const // never throws
00652     { return _M_ptr; }
00653 
00654     // implicit conversion to "bool"
00655   private:
00656     typedef _Tp* shared_ptr::*__unspecified_bool_type;
00657 
00658   public:
00659     operator __unspecified_bool_type() const // never throws
00660     { return _M_ptr == 0 ? 0 : &shared_ptr::_M_ptr; }
00661 
00662     bool
00663     unique() const // never throws
00664     { return _M_refcount.unique(); }
00665 
00666     long
00667     use_count() const // never throws
00668     { return _M_refcount.use_count(); }
00669 
00670     void
00671     swap(shared_ptr<_Tp>& __other) // never throws
00672     {
00673       std::swap(_M_ptr, __other._M_ptr);
00674       _M_refcount.swap(__other._M_refcount);
00675     }
00676 
00677     void*
00678     _M_get_deleter(const std::type_info& __ti) const
00679     { return _M_refcount.get_deleter(__ti); }
00680 
00681   private:
00682     template <typename _Tp1>
00683       bool
00684       _M_less(const shared_ptr<_Tp1>& __rhs) const
00685       { return _M_refcount < __rhs._M_refcount; }
00686 
00687     template <typename _Tp1> friend class shared_ptr;
00688     template <typename _Tp1> friend class weak_ptr;
00689 
00690     // friends injected into enclosing namespace and found by ADL:
00691     template <typename _Tp1>
00692       friend inline bool
00693       operator==(const shared_ptr& __a, const shared_ptr<_Tp1>& __b)
00694       { return __a.get() == __b.get(); }
00695 
00696     template <typename _Tp1>
00697       friend inline bool
00698       operator!=(const shared_ptr& __a, const shared_ptr<_Tp1>& __b)
00699       { return __a.get() != __b.get(); }
00700 
00701     template <typename _Tp1>
00702       friend inline bool
00703       operator<(const shared_ptr& __a, const shared_ptr<_Tp1>& __b)
00704       { return __a._M_less(__b); }
00705 
00706     _Tp*         _M_ptr;         // contained pointer
00707     shared_count _M_refcount;    // reference counter
00708   };  // shared_ptr
00709 
00710 // 2.2.3.8 shared_ptr specialized algorithms.
00711 template<typename _Tp>
00712   inline void
00713   swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b)
00714   { __a.swap(__b); }
00715 
00716 // 2.2.3.9 shared_ptr casts
00717 
00718 /** @warning The seemingly equivalent
00719  *           <code>shared_ptr<T>(static_cast<T*>(r.get()))</code>
00720  *           will eventually result in undefined behaviour,
00721  *           attempting to delete the same object twice.
00722  */
00723 template <typename _Tp, typename _Tp1>
00724   shared_ptr<_Tp>
00725   static_pointer_cast(const shared_ptr<_Tp1>& __r)
00726   {
00727     return shared_ptr<_Tp>(__r, __static_cast_tag());
00728   }
00729 
00730 /** @warning The seemingly equivalent
00731  *           <code>shared_ptr<T>(const_cast<T*>(r.get()))</code>
00732  *           will eventually result in undefined behaviour,
00733  *           attempting to delete the same object twice.
00734  */
00735 template <typename _Tp, typename _Tp1>
00736   shared_ptr<_Tp>
00737   const_pointer_cast(const shared_ptr<_Tp1>& __r)
00738   {
00739     return shared_ptr<_Tp>(__r, __const_cast_tag());
00740   }
00741 
00742 /** @warning The seemingly equivalent
00743  *           <code>shared_ptr<T>(dynamic_cast<T*>(r.get()))</code>
00744  *           will eventually result in undefined behaviour,
00745  *           attempting to delete the same object twice.
00746  */
00747 template <typename _Tp, typename _Tp1>
00748   shared_ptr<_Tp>
00749   dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
00750   {
00751     return shared_ptr<_Tp>(__r, __dynamic_cast_tag());
00752   }
00753 
00754 // 2.2.3.7 shared_ptr I/O
00755 template <typename _Ch, typename _Tr, typename _Tp>
00756   std::basic_ostream<_Ch, _Tr>&
00757   operator<<(std::basic_ostream<_Ch, _Tr>& __os, const shared_ptr<_Tp>& __p)
00758   {
00759     __os << __p.get();
00760     return __os;
00761   }
00762 
00763 // 2.2.3.10 shared_ptr get_deleter (experimental)
00764 template <typename _Del, typename _Tp>
00765   inline _Del*
00766   get_deleter(const shared_ptr<_Tp>& __p)
00767   { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
00768 
00769 
00770 template <typename _Tp>
00771   class weak_ptr
00772   {
00773   public:
00774 
00775     typedef _Tp element_type;
00776 
00777     weak_ptr()
00778     : _M_ptr(0), _M_refcount() // never throws
00779     { }
00780 
00781   //  generated copy constructor, assignment, destructor are fine
00782 
00783   //
00784   //  The "obvious" converting constructor implementation:
00785   //
00786   //  template<class Y>
00787   //  weak_ptr(weak_ptr<Y> const & r): _M_ptr(r._M_ptr), _M_refcount(r._M_refcount) // never throws
00788   //  {
00789   //  }
00790   //
00791   //  has a serious problem.
00792   //
00793   //  r._M_ptr may already have been invalidated. The _M_ptr(r._M_ptr)
00794   //  conversion may require access to *r._M_ptr (virtual inheritance).
00795   //
00796   //  It is not possible to avoid spurious access violations since
00797   //  in multithreaded programs r._M_ptr may be invalidated at any point.
00798   //
00799 
00800     template <typename _Tp1>
00801       weak_ptr(const weak_ptr<_Tp1>& r)
00802       : _M_refcount(r._M_refcount) // never throws
00803       {
00804         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00805         _M_ptr = r.lock().get();
00806       }
00807 
00808     template <typename _Tp1>
00809       weak_ptr(const shared_ptr<_Tp1>& r)
00810       : _M_ptr(r._M_ptr), _M_refcount(r._M_refcount) // never throws
00811       {
00812         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00813       }
00814 
00815     template <typename _Tp1>
00816       weak_ptr&
00817       operator=(const weak_ptr<_Tp1>& r) // never throws
00818       {
00819         _M_ptr = r.lock().get();
00820         _M_refcount = r._M_refcount;
00821         return *this;
00822       }
00823 
00824     template <typename _Tp1>
00825       weak_ptr&
00826       operator=(const shared_ptr<_Tp1>& r) // never throws
00827       {
00828         _M_ptr = r._M_ptr;
00829         _M_refcount = r._M_refcount;
00830         return *this;
00831       }
00832 
00833     shared_ptr<_Tp>
00834     lock() const // never throws
00835     {
00836 #ifdef __GTHREADS
00837 
00838       // optimization: avoid throw overhead
00839       if (expired())
00840       {
00841         return shared_ptr<element_type>();
00842       }
00843 
00844       try
00845       {
00846         return shared_ptr<element_type>(*this);
00847       }
00848       catch (const bad_weak_ptr&)
00849       {
00850         // Q: how can we get here?
00851         // A: another thread may have invalidated r after the use_count test above.
00852         return shared_ptr<element_type>();
00853       }
00854 
00855 #else
00856 
00857       // optimization: avoid try/catch overhead when single threaded
00858       return expired() ? shared_ptr<element_type>() : shared_ptr<element_type>(*this);
00859 
00860 #endif
00861     } // XXX MT
00862 
00863 
00864     long
00865     use_count() const // never throws
00866     { return _M_refcount.use_count(); }
00867 
00868     bool
00869     expired() const // never throws
00870     { return _M_refcount.use_count() == 0; }
00871 
00872     void
00873     reset() // never throws
00874     { weak_ptr().swap(*this); }
00875 
00876     void
00877     swap(weak_ptr& __s) // never throws
00878     {
00879       std::swap(_M_ptr, __s._M_ptr);
00880       _M_refcount.swap(__s._M_refcount);
00881     }
00882 
00883   private:
00884 
00885     template <typename _Tp1>
00886       bool
00887       _M_less(const weak_ptr<_Tp1>& __rhs) const
00888       { return _M_refcount < __rhs._M_refcount; }
00889 
00890     // used by __enable_shared_from_this
00891     void
00892     _M_assign(_Tp* __ptr, const shared_count& __refcount)
00893     {
00894       _M_ptr = __ptr;
00895       _M_refcount = __refcount;
00896     }
00897 
00898     // friend injected into namespace and found by ADL
00899 
00900     template <typename _Tp1>
00901       friend inline bool
00902       operator<(const weak_ptr& __lhs, const weak_ptr<_Tp1>& __rhs)
00903       { return __lhs._M_less(__rhs); }
00904 
00905     template <typename _Tp1> friend class weak_ptr;
00906     template <typename _Tp1> friend class shared_ptr;
00907     friend class enable_shared_from_this<_Tp>;
00908 
00909     _Tp*       _M_ptr;           // contained pointer
00910     weak_count _M_refcount;      // reference counter
00911 
00912   };  // weak_ptr
00913 
00914 // 2.2.4.7 weak_ptr specialized algorithms.
00915 template<typename _Tp>
00916   void
00917   swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b)
00918   { __a.swap(__b); }
00919 
00920 
00921 template <typename _Tp>
00922   class enable_shared_from_this
00923   {
00924   protected:
00925 
00926     enable_shared_from_this()
00927     { }
00928 
00929     enable_shared_from_this(const enable_shared_from_this&)
00930     { }
00931 
00932     enable_shared_from_this&
00933     operator=(const enable_shared_from_this&)
00934     { return *this; }
00935 
00936     ~enable_shared_from_this()
00937     { }
00938 
00939   public:
00940 
00941     shared_ptr<_Tp>
00942     shared_from_this()
00943     {
00944       shared_ptr<_Tp> p(this->_M_weak_this);
00945       return p;
00946     }
00947 
00948     shared_ptr<const _Tp>
00949     shared_from_this() const
00950     {
00951       shared_ptr<const _Tp> p(this->_M_weak_this);
00952       return p;
00953     }
00954 
00955   private:
00956     template <typename _Tp1>
00957       void
00958       _M_weak_assign(_Tp1* __p, const shared_count& __n) const
00959       { _M_weak_this._M_assign(__p, __n); }
00960 
00961     template <typename _Tp1>
00962       friend void
00963       __enable_shared_from_this( const shared_count& __pn, const enable_shared_from_this* __pe, const _Tp1* __px)
00964       {
00965         if(__pe != 0)
00966           __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
00967       }
00968 
00969     mutable weak_ptr<_Tp> _M_weak_this;
00970   };
00971 
00972 } // namespace tr1
00973 
00974 } // namespace std
00975 
00976 #endif

Generated on Tue May 23 12:55:25 2006 for libstdc++ source by  doxygen 1.4.4