# boost_shared_ptr.h

Go to the documentation of this file.

    00001 // <tr1/boost_shared_ptr.h> -*- C++ -*-
    00002
    00003 // Copyright (C) 2005, 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    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 tr1/boost_shared_ptr.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
    00058 {
    00059 _GLIBCXX_BEGIN_NAMESPACE(tr1)
    00060
    00061   class bad_weak_ptr : public std::exception
    00062   {
    00063   public:
    00064     virtual char const*
    00065     what() const throw()
    00066     { return "tr1::bad_weak_ptr"; }
    00067   };
    00068
    00069   // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
    00070   inline void
    00071   __throw_bad_weak_ptr()
    00072   {
    00073 #if __EXCEPTIONS
    00074     throw bad_weak_ptr();
    00075 #else
    00076     std::abort();
    00077 #endif
    00078   }
    00079
    00080   using __gnu_cxx::_Lock_policy;
    00081   using __gnu_cxx::__default_lock_policy;
    00082   using __gnu_cxx::_S_single;
    00083   using __gnu_cxx::_S_mutex;
    00084   using __gnu_cxx::_S_atomic;
    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   // Empty helper class except when the template argument is _S_mutex.
    00098   template<_Lock_policy _Lp>
    00099     class _Mutex_base
    00100     { };
    00101
    00102   template<>
    00103     class _Mutex_base<_S_mutex>
    00104     : public __gnu_cxx::__mutex
    00105     { };
    00106
    00107   template<_Lock_policy _Lp = __default_lock_policy>
    00108     class _Sp_counted_base
    00109     : public _Mutex_base<_Lp>
    00110     {
    00111     public:
    00112       _Sp_counted_base()
    00113       : _M_use_count(1), _M_weak_count(1) { }
    00114
    00115       virtual
    00116       ~_Sp_counted_base() // nothrow
    00117       { }
    00118
    00119       // Called when _M_use_count drops to zero, to release the resources
    00120       // managed by *this.
    00121       virtual void
    00122       _M_dispose() = 0; // nothrow
    00123
    00124       // Called when _M_weak_count drops to zero.
    00125       virtual void
    00126       _M_destroy() // nothrow
    00127       { delete this; }
    00128
    00129       virtual void*
    00130       _M_get_deleter(const std::type_info&) = 0;
    00131
    00132       void
    00133       _M_add_ref_copy()
    00134       { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
    00135
    00136       void
    00137       _M_add_ref_lock();
    00138
    00139       void
    00140       _M_release() // nothrow
    00141       {
    00142     if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count,
    00143                            -1) == 1)
    00144       {
    00145         _M_dispose();
    00146 #ifdef __GTHREADS
    00147         _GLIBCXX_READ_MEM_BARRIER;
    00148         _GLIBCXX_WRITE_MEM_BARRIER;
    00149 #endif
    00150         if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
    00151                                -1) == 1)
    00152           _M_destroy();
    00153       }
    00154       }
    00155
    00156       void
    00157       _M_weak_add_ref() // nothrow
    00158       { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
    00159
    00160       void
    00161       _M_weak_release() // nothrow
    00162       {
    00163     if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
    00164       {
    00165 #ifdef __GTHREADS
    00166         _GLIBCXX_READ_MEM_BARRIER;
    00167         _GLIBCXX_WRITE_MEM_BARRIER;
    00168 #endif
    00169         _M_destroy();
    00170       }
    00171       }
    00172
    00173       long
    00174       _M_get_use_count() const // nothrow
    00175       { return _M_use_count; }  // XXX is this MT safe?
    00176
    00177     private:
    00178       _Sp_counted_base(_Sp_counted_base const&);
    00179       _Sp_counted_base& operator=(_Sp_counted_base const&);
    00180
    00181       _Atomic_word  _M_use_count;     // #shared
    00182       _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
    00183     };
    00184
    00185   template<>
    00186     inline void
    00187     _Sp_counted_base<_S_single>::
    00188     _M_add_ref_lock()
    00189     {
    00190       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
    00191     {
    00192       _M_use_count = 0;
    00193       __throw_bad_weak_ptr();
    00194     }
    00195     }
    00196
    00197 #ifdef __GTHREADS
    00198   template<>
    00199     inline void
    00200     _Sp_counted_base<_S_mutex>::
    00201     _M_add_ref_lock()
    00202     {
    00203       __gnu_cxx::__scoped_lock sentry(*this);
    00204       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
    00205     {
    00206       _M_use_count = 0;
    00207       __throw_bad_weak_ptr();
    00208     }
    00209     }
    00210 #endif
    00211
    00212   template<>
    00213     inline void
    00214     _Sp_counted_base<_S_atomic>::
    00215     _M_add_ref_lock()
    00216     {
    00217       // Perform lock-free add-if-not-zero operation.
    00218       _Atomic_word __count;
    00219       do
    00220     {
    00221       __count = _M_use_count;
    00222       if (__count == 0)
    00223         __throw_bad_weak_ptr();
    00224
    00225       // Replace the current counter value with the old value + 1, as
    00226       // long as it's not changed meanwhile.
    00227     }
    00228       while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
    00229                        __count + 1));
    00230     }
    00231
    00232   template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
    00233     class _Sp_counted_base_impl
    00234     : public _Sp_counted_base<_Lp>
    00235     {
    00236     public:
    00237       /**
    00238        *  @brief
    00239        *  @pre     __d(__p) must not throw.
    00240        */
    00241       _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
    00242       : _M_ptr(__p), _M_del(__d) { }
    00243
    00244       virtual void
    00245       _M_dispose() // nothrow
    00246       { _M_del(_M_ptr); }
    00247
    00248       virtual void*
    00249       _M_get_deleter(const std::type_info& __ti)
    00250       { return __ti == typeid(_Deleter) ? &_M_del : 0; }
    00251
    00252     private:
    00253       _Sp_counted_base_impl(const _Sp_counted_base_impl&);
    00254       _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
    00255
    00256       _Ptr      _M_ptr;  // copy constructor must not throw
    00257       _Deleter  _M_del;  // copy constructor must not throw
    00258     };
    00259
    00260   template<_Lock_policy _Lp = __default_lock_policy>
    00261     class __weak_count;
    00262
    00263   template<_Lock_policy _Lp = __default_lock_policy>
    00264     class __shared_count
    00265     {
    00266     public:
    00267       __shared_count()
    00268       : _M_pi(0) // nothrow
    00269       { }
    00270
    00271       template<typename _Ptr, typename _Deleter>
    00272         __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
    00273         {
    00274       try
    00275         {
    00276           _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
    00277         }
    00278       catch(...)
    00279         {
    00280           __d(__p); // Call _Deleter on __p.
    00281           __throw_exception_again;
    00282         }
    00283     }
    00284
    00285       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
    00286       template<typename _Tp>
    00287         explicit
    00288         __shared_count(std::auto_ptr<_Tp>& __r)
    00289     : _M_pi(new _Sp_counted_base_impl<_Tp*,
    00290         _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
    00291         { __r.release(); }
    00292
    00293       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
    00294       explicit
    00295       __shared_count(const __weak_count<_Lp>& __r);
    00296
    00297       ~__shared_count() // nothrow
    00298       {
    00299     if (_M_pi != 0)
    00300       _M_pi->_M_release();
    00301       }
    00302
    00303       __shared_count(const __shared_count& __r)
    00304       : _M_pi(__r._M_pi) // nothrow
    00305       {
    00306     if (_M_pi != 0)
    00307       _M_pi->_M_add_ref_copy();
    00308       }
    00309
    00310       __shared_count&
    00311       operator=(const __shared_count& __r) // nothrow
    00312       {
    00313     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00314     if (__tmp != _M_pi)
    00315       {
    00316         if (__tmp != 0)
    00317           __tmp->_M_add_ref_copy();
    00318         if (_M_pi != 0)
    00319           _M_pi->_M_release();
    00320         _M_pi = __tmp;
    00321       }
    00322     return *this;
    00323       }
    00324
    00325       void
    00326       _M_swap(__shared_count& __r) // nothrow
    00327       {
    00328     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00329     __r._M_pi = _M_pi;
    00330     _M_pi = __tmp;
    00331       }
    00332
    00333       long
    00334       _M_get_use_count() const // nothrow
    00335       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
    00336
    00337       bool
    00338       _M_unique() const // nothrow
    00339       { return this->_M_get_use_count() == 1; }
    00340
    00341       friend inline bool
    00342       operator==(const __shared_count& __a, const __shared_count& __b)
    00343       { return __a._M_pi == __b._M_pi; }
    00344
    00345       friend inline bool
    00346       operator<(const __shared_count& __a, const __shared_count& __b)
    00347       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
    00348
    00349       void*
    00350       _M_get_deleter(const std::type_info& __ti) const
    00351       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
    00352
    00353     private:
    00354       friend class __weak_count<_Lp>;
    00355
    00356       _Sp_counted_base<_Lp>*  _M_pi;
    00357     };
    00358
    00359   template<_Lock_policy _Lp>
    00360     class __weak_count
    00361     {
    00362     public:
    00363       __weak_count()
    00364       : _M_pi(0) // nothrow
    00365       { }
    00366
    00367       __weak_count(const __shared_count<_Lp>& __r)
    00368       : _M_pi(__r._M_pi) // nothrow
    00369       {
    00370     if (_M_pi != 0)
    00371       _M_pi->_M_weak_add_ref();
    00372       }
    00373
    00374       __weak_count(const __weak_count<_Lp>& __r)
    00375       : _M_pi(__r._M_pi) // nothrow
    00376       {
    00377     if (_M_pi != 0)
    00378       _M_pi->_M_weak_add_ref();
    00379       }
    00380
    00381       ~__weak_count() // nothrow
    00382       {
    00383     if (_M_pi != 0)
    00384       _M_pi->_M_weak_release();
    00385       }
    00386
    00387       __weak_count<_Lp>&
    00388       operator=(const __shared_count<_Lp>& __r) // nothrow
    00389       {
    00390     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00391     if (__tmp != 0)
    00392       __tmp->_M_weak_add_ref();
    00393     if (_M_pi != 0)
    00394       _M_pi->_M_weak_release();
    00395     _M_pi = __tmp;
    00396     return *this;
    00397       }
    00398
    00399       __weak_count<_Lp>&
    00400       operator=(const __weak_count<_Lp>& __r) // nothrow
    00401       {
    00402     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00403     if (__tmp != 0)
    00404       __tmp->_M_weak_add_ref();
    00405     if (_M_pi != 0)
    00406       _M_pi->_M_weak_release();
    00407     _M_pi = __tmp;
    00408     return *this;
    00409       }
    00410
    00411       void
    00412       _M_swap(__weak_count<_Lp>& __r) // nothrow
    00413       {
    00414     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00415     __r._M_pi = _M_pi;
    00416     _M_pi = __tmp;
    00417       }
    00418
    00419       long
    00420       _M_get_use_count() const // nothrow
    00421       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
    00422
    00423       friend inline bool
    00424       operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
    00425       { return __a._M_pi == __b._M_pi; }
    00426
    00427       friend inline bool
    00428       operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
    00429       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
    00430
    00431     private:
    00432       friend class __shared_count<_Lp>;
    00433
    00434       _Sp_counted_base<_Lp>*  _M_pi;
    00435     };
    00436
    00437   template<_Lock_policy _Lp>
    00438     inline
    00439     __shared_count<_Lp>::
    00440     __shared_count(const __weak_count<_Lp>& __r)
    00441     : _M_pi(__r._M_pi)
    00442     {
    00443       if (_M_pi != 0)
    00444     _M_pi->_M_add_ref_lock();
    00445       else
    00446     __throw_bad_weak_ptr();
    00447     }
    00448
    00449
    00450   // Forward declarations.
    00451   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    00452     class __shared_ptr;
    00453
    00454   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    00455     class __weak_ptr;
    00456
    00457   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    00458     class __enable_shared_from_this;
    00459
    00460   template<typename _Tp>
    00461     class shared_ptr;
    00462
    00463   template<typename _Tp>
    00464     class weak_ptr;
    00465
    00466   template<typename _Tp>
    00467     class enable_shared_from_this;
    00468
    00469   // Support for enable_shared_from_this.
    00470
    00471   // Friend of __enable_shared_from_this.
    00472   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
    00473     void
    00474     __enable_shared_from_this_helper(const __shared_count<_Lp>&,
    00475                      const __enable_shared_from_this<_Tp1,
    00476                      _Lp>*, const _Tp2*);
    00477
    00478   // Friend of enable_shared_from_this.
    00479   template<typename _Tp1, typename _Tp2>
    00480     void
    00481     __enable_shared_from_this_helper(const __shared_count<>&,
    00482                      const enable_shared_from_this<_Tp1>*,
    00483                      const _Tp2*);
    00484
    00485   template<_Lock_policy _Lp>
    00486     inline void
    00487     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
    00488     { }
    00489
    00490
    00491   struct __static_cast_tag { };
    00492   struct __const_cast_tag { };
    00493   struct __dynamic_cast_tag { };
    00494
    00495   /**
    00496    *  @class shared_ptr <tr1/memory>
    00497    *
    00498    *  A smart pointer with reference-counted copy semantics.
    00499    *  The object pointed to is deleted when the last shared_ptr pointing to
    00500    *  it is destroyed or reset.
    00501    */
    00502   template<typename _Tp, _Lock_policy _Lp>
    00503     class __shared_ptr
    00504     {
    00505     public:
    00506       typedef _Tp   element_type;
    00507
    00508       /** @brief  Construct an empty %__shared_ptr.
    00509        *  @post   use_count()==0 && get()==0
    00510        */
    00511       __shared_ptr()
    00512       : _M_ptr(0), _M_refcount() // never throws
    00513       { }
    00514
    00515       /** @brief  Construct a %__shared_ptr that owns the pointer @a __p.
    00516        *  @param  __p  A pointer that is convertible to element_type*.
    00517        *  @post   use_count() == 1 && get() == __p
    00518        *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
    00519        */
    00520       template<typename _Tp1>
    00521         explicit
    00522         __shared_ptr(_Tp1* __p)
    00523     : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
    00524         {
    00525       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00526       // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
    00527       __enable_shared_from_this_helper(_M_refcount, __p, __p);
    00528     }
    00529
    00530       //
    00531       // Requirements: _Deleter' copy constructor and destructor must not throw
    00532       //
    00533       // __shared_ptr will release __p by calling __d(__p)
    00534       //
    00535       /** @brief  Construct a %__shared_ptr that owns the pointer @a __p
    00536        *          and the deleter @a __d.
    00537        *  @param  __p  A pointer.
    00538        *  @param  __d  A deleter.
    00539        *  @post   use_count() == 1 && get() == __p
    00540        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
    00541        */
    00542       template<typename _Tp1, typename _Deleter>
    00543         __shared_ptr(_Tp1* __p, _Deleter __d)
    00544     : _M_ptr(__p), _M_refcount(__p, __d)
    00545         {
    00546       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00547       // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
    00548       __enable_shared_from_this_helper(_M_refcount, __p, __p);
    00549     }
    00550
    00551       //  generated copy constructor, assignment, destructor are fine.
    00552
    00553       /** @brief  If @a __r is empty, constructs an empty %__shared_ptr;
    00554        *          otherwise construct a %__shared_ptr that shares ownership
    00555        *          with @a __r.
    00556        *  @param  __r  A %__shared_ptr.
    00557        *  @post   get() == __r.get() && use_count() == __r.use_count()
    00558        *  @throw  std::bad_alloc, in which case
    00559        */
    00560       template<typename _Tp1>
    00561         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
    00562     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    00563         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
    00564
    00565       /** @brief  Constructs a %__shared_ptr that shares ownership with @a __r
    00566        *          and stores a copy of the pointer stored in @a __r.
    00567        *  @param  __r  A weak_ptr.
    00568        *  @post   use_count() == __r.use_count()
    00569        *  @throw  bad_weak_ptr when __r.expired(),
    00570        *          in which case the constructor has no effect.
    00571        */
    00572       template<typename _Tp1>
    00573         explicit
    00574         __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    00575     : _M_refcount(__r._M_refcount) // may throw
    00576         {
    00577       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00578       // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
    00579       // did not throw.
    00580       _M_ptr = __r._M_ptr;
    00581     }
    00582
    00583       /**
    00584        * @post use_count() == 1 and __r.get() == 0
    00585        */
    00586       template<typename _Tp1>
    00587         explicit
    00588         __shared_ptr(std::auto_ptr<_Tp1>& __r)
    00589     : _M_ptr(__r.get()), _M_refcount()
    00590         {
    00591       // TODO requires __r.release() convertible to _Tp*, _Tp1 is complete,
    00592       // delete __r.release() well-formed
    00593       _Tp1* __tmp = __r.get();
    00594       _M_refcount = __shared_count<_Lp>(__r);
    00595       __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
    00596     }
    00597
    00598       template<typename _Tp1>
    00599         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
    00600     : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
    00601       _M_refcount(__r._M_refcount)
    00602         { }
    00603
    00604       template<typename _Tp1>
    00605         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
    00606     : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
    00607       _M_refcount(__r._M_refcount)
    00608         { }
    00609
    00610       template<typename _Tp1>
    00611         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
    00612     : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
    00613       _M_refcount(__r._M_refcount)
    00614         {
    00615       if (_M_ptr == 0) // need to allocate new counter -- the cast failed
    00616         _M_refcount = __shared_count<_Lp>();
    00617     }
    00618
    00619       template<typename _Tp1>
    00620         __shared_ptr&
    00621         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
    00622         {
    00623       _M_ptr = __r._M_ptr;
    00624       _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
    00625       return *this;
    00626     }
    00627
    00628       template<typename _Tp1>
    00629         __shared_ptr&
    00630         operator=(std::auto_ptr<_Tp1>& __r)
    00631         {
    00632       __shared_ptr(__r).swap(*this);
    00633       return *this;
    00634     }
    00635
    00636       void
    00637       reset() // never throws
    00638       { __shared_ptr().swap(*this); }
    00639
    00640       template<typename _Tp1>
    00641         void
    00642         reset(_Tp1* __p) // _Tp1 must be complete.
    00643         {
    00644       // Catch self-reset errors.
    00645       _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
    00646       __shared_ptr(__p).swap(*this);
    00647     }
    00648
    00649       template<typename _Tp1, typename _Deleter>
    00650         void
    00651         reset(_Tp1* __p, _Deleter __d)
    00652         { __shared_ptr(__p, __d).swap(*this); }
    00653
    00654       // Allow class instantiation when _Tp is [cv-qual] void.
    00655       typename add_reference<_Tp>::type
    00656       operator*() const // never throws
    00657       {
    00658     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    00659     return *_M_ptr;
    00660       }
    00661
    00662       _Tp*
    00663       operator->() const // never throws
    00664       {
    00665     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    00666     return _M_ptr;
    00667       }
    00668
    00669       _Tp*
    00670       get() const // never throws
    00671       { return _M_ptr; }
    00672
    00673       // Implicit conversion to "bool"
    00674     private:
    00675       typedef _Tp* __shared_ptr::*__unspecified_bool_type;
    00676
    00677     public:
    00678       operator __unspecified_bool_type() const // never throws
    00679       { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
    00680
    00681       bool
    00682       unique() const // never throws
    00683       { return _M_refcount._M_unique(); }
    00684
    00685       long
    00686       use_count() const // never throws
    00687       { return _M_refcount._M_get_use_count(); }
    00688
    00689       void
    00690       swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
    00691       {
    00692     std::swap(_M_ptr, __other._M_ptr);
    00693     _M_refcount._M_swap(__other._M_refcount);
    00694       }
    00695
    00696     private:
    00697       void*
    00698       _M_get_deleter(const std::type_info& __ti) const
    00699       { return _M_refcount._M_get_deleter(__ti); }
    00700
    00701       template<typename _Tp1, _Lock_policy _Lp1>
    00702         bool
    00703         _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
    00704         { return _M_refcount < __rhs._M_refcount; }
    00705
    00706       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
    00707       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
    00708
    00709       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
    00710         friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
    00711
    00712       // Friends injected into enclosing namespace and found by ADL:
    00713       template<typename _Tp1>
    00714         friend inline bool
    00715         operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    00716         { return __a.get() == __b.get(); }
    00717
    00718       template<typename _Tp1>
    00719         friend inline bool
    00720         operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    00721         { return __a.get() != __b.get(); }
    00722
    00723       template<typename _Tp1>
    00724         friend inline bool
    00725         operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    00726         { return __a._M_less(__b); }
    00727
    00728       _Tp*             _M_ptr;         // Contained pointer.
    00729       __shared_count<_Lp>  _M_refcount;    // Reference counter.
    00730     };
    00731
    00732   // 2.2.3.8 shared_ptr specialized algorithms.
    00733   template<typename _Tp, _Lock_policy _Lp>
    00734     inline void
    00735     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
    00736     { __a.swap(__b); }
    00737
    00738   // 2.2.3.9 shared_ptr casts
    00739   /** @warning The seemingly equivalent
    00740    *           <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
    00741    *           will eventually result in undefined behaviour,
    00742    *           attempting to delete the same object twice.
    00743    */
    00744   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    00745     __shared_ptr<_Tp, _Lp>
    00746     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    00747     { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
    00748
    00749   /** @warning The seemingly equivalent
    00750    *           <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
    00751    *           will eventually result in undefined behaviour,
    00752    *           attempting to delete the same object twice.
    00753    */
    00754   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    00755     __shared_ptr<_Tp, _Lp>
    00756     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    00757     { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
    00758
    00759   /** @warning The seemingly equivalent
    00760    *           <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
    00761    *           will eventually result in undefined behaviour,
    00762    *           attempting to delete the same object twice.
    00763    */
    00764   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    00765     __shared_ptr<_Tp, _Lp>
    00766     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    00767     { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
    00768
    00769   // 2.2.3.7 shared_ptr I/O
    00770   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
    00771     std::basic_ostream<_Ch, _Tr>&
    00772     operator<<(std::basic_ostream<_Ch, _Tr>& __os,
    00773            const __shared_ptr<_Tp, _Lp>& __p)
    00774     {
    00775       __os << __p.get();
    00776       return __os;
    00777     }
    00778
    00779   // 2.2.3.10 shared_ptr get_deleter (experimental)
    00780   template<typename _Del, typename _Tp, _Lock_policy _Lp>
    00781     inline _Del*
    00782     get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
    00783     { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
    00784
    00785
    00786   template<typename _Tp, _Lock_policy _Lp>
    00787     class __weak_ptr
    00788     {
    00789     public:
    00790       typedef _Tp element_type;
    00791
    00792       __weak_ptr()
    00793       : _M_ptr(0), _M_refcount() // never throws
    00794       { }
    00795
    00796       // Generated copy constructor, assignment, destructor are fine.
    00797
    00798       // The "obvious" converting constructor implementation:
    00799       //
    00800       //  template<typename _Tp1>
    00801       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    00802       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    00803       //    { }
    00804       //
    00805       // has a serious problem.
    00806       //
    00807       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
    00808       //  conversion may require access to *__r._M_ptr (virtual inheritance).
    00809       //
    00810       // It is not possible to avoid spurious access violations since
    00811       // in multithreaded programs __r._M_ptr may be invalidated at any point.
    00812       template<typename _Tp1>
    00813         __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    00814     : _M_refcount(__r._M_refcount) // never throws
    00815         {
    00816       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00817       _M_ptr = __r.lock().get();
    00818     }
    00819
    00820       template<typename _Tp1>
    00821         __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
    00822     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    00823         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
    00824
    00825       template<typename _Tp1>
    00826         __weak_ptr&
    00827         operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
    00828         {
    00829       _M_ptr = __r.lock().get();
    00830       _M_refcount = __r._M_refcount;
    00831       return *this;
    00832     }
    00833
    00834       template<typename _Tp1>
    00835         __weak_ptr&
    00836         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
    00837         {
    00838       _M_ptr = __r._M_ptr;
    00839       _M_refcount = __r._M_refcount;
    00840       return *this;
    00841     }
    00842
    00843       __shared_ptr<_Tp, _Lp>
    00844       lock() const // never throws
    00845       {
    00846 #ifdef __GTHREADS
    00847     // Optimization: avoid throw overhead.
    00848     if (expired())
    00849       return __shared_ptr<element_type, _Lp>();
    00850
    00851     try
    00852       {
    00853         return __shared_ptr<element_type, _Lp>(*this);
    00854       }
    00855     catch(const bad_weak_ptr&)
    00856       {
    00857         // Q: How can we get here?
    00858         // A: Another thread may have invalidated r after the
    00859         //    use_count test above.
    00860         return __shared_ptr<element_type, _Lp>();
    00861       }
    00862
    00863 #else
    00864     // Optimization: avoid try/catch overhead when single threaded.
    00865     return expired() ? __shared_ptr<element_type, _Lp>()
    00866                      : __shared_ptr<element_type, _Lp>(*this);
    00867
    00868 #endif
    00869       } // XXX MT
    00870
    00871       long
    00872       use_count() const // never throws
    00873       { return _M_refcount._M_get_use_count(); }
    00874
    00875       bool
    00876       expired() const // never throws
    00877       { return _M_refcount._M_get_use_count() == 0; }
    00878
    00879       void
    00880       reset() // never throws
    00881       { __weak_ptr().swap(*this); }
    00882
    00883       void
    00884       swap(__weak_ptr& __s) // never throws
    00885       {
    00886     std::swap(_M_ptr, __s._M_ptr);
    00887     _M_refcount._M_swap(__s._M_refcount);
    00888       }
    00889
    00890     private:
    00891       // Used by __enable_shared_from_this.
    00892       void
    00893       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
    00894       {
    00895     _M_ptr = __ptr;
    00896     _M_refcount = __refcount;
    00897       }
    00898
    00899       template<typename _Tp1>
    00900         bool
    00901         _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
    00902         { return _M_refcount < __rhs._M_refcount; }
    00903
    00904       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
    00905       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
    00906       friend class __enable_shared_from_this<_Tp, _Lp>;
    00907       friend class enable_shared_from_this<_Tp>;
    00908
    00909       // Friend injected into namespace and found by ADL.
    00910       template<typename _Tp1>
    00911         friend inline bool
    00912         operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
    00913         { return __lhs._M_less(__rhs); }
    00914
    00915       _Tp*           _M_ptr;         // Contained pointer.
    00916       __weak_count<_Lp>  _M_refcount;    // Reference counter.
    00917     };
    00918
    00919   // 2.2.4.7 weak_ptr specialized algorithms.
    00920   template<typename _Tp, _Lock_policy _Lp>
    00921     inline void
    00922     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
    00923     { __a.swap(__b); }
    00924
    00925
    00926   template<typename _Tp, _Lock_policy _Lp>
    00927     class __enable_shared_from_this
    00928     {
    00929     protected:
    00930       __enable_shared_from_this() { }
    00931
    00932       __enable_shared_from_this(const __enable_shared_from_this&) { }
    00933
    00934       __enable_shared_from_this&
    00935       operator=(const __enable_shared_from_this&)
    00936       { return *this; }
    00937
    00938       ~__enable_shared_from_this() { }
    00939
    00940     public:
    00941       __shared_ptr<_Tp, _Lp>
    00942       shared_from_this()
    00943       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
    00944
    00945       __shared_ptr<const _Tp, _Lp>
    00946       shared_from_this() const
    00947       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
    00948
    00949     private:
    00950       template<typename _Tp1>
    00951         void
    00952         _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
    00953         { _M_weak_this._M_assign(__p, __n); }
    00954
    00955       template<typename _Tp1>
    00956         friend void
    00957         __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
    00958                      const __enable_shared_from_this* __pe,
    00959                      const _Tp1* __px)
    00960         {
    00961       if (__pe != 0)
    00962         __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
    00963     }
    00964
    00965       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
    00966     };
    00967
    00968
    00969   // The actual TR1 shared_ptr, with forwarding constructors and
    00970   // assignment operators.
    00971   template<typename _Tp>
    00972     class shared_ptr
    00973     : public __shared_ptr<_Tp>
    00974     {
    00975     public:
    00976       shared_ptr()
    00977       : __shared_ptr<_Tp>() { }
    00978
    00979       template<typename _Tp1>
    00980         explicit
    00981         shared_ptr(_Tp1* __p)
    00982     : __shared_ptr<_Tp>(__p) { }
    00983
    00984       template<typename _Tp1, typename _Deleter>
    00985         shared_ptr(_Tp1* __p, _Deleter __d)
    00986     : __shared_ptr<_Tp>(__p, __d) { }
    00987
    00988       template<typename _Tp1>
    00989         shared_ptr(const shared_ptr<_Tp1>& __r)
    00990     : __shared_ptr<_Tp>(__r) { }
    00991
    00992       template<typename _Tp1>
    00993         explicit
    00994         shared_ptr(const weak_ptr<_Tp1>& __r)
    00995     : __shared_ptr<_Tp>(__r) { }
    00996
    00997       template<typename _Tp1>
    00998         explicit
    00999         shared_ptr(std::auto_ptr<_Tp1>& __r)
    01000     : __shared_ptr<_Tp>(__r) { }
    01001
    01002       template<typename _Tp1>
    01003         shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
    01004     : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
    01005
    01006       template<typename _Tp1>
    01007         shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
    01008     : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
    01009
    01010       template<typename _Tp1>
    01011         shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
    01012     : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
    01013
    01014       template<typename _Tp1>
    01015         shared_ptr&
    01016         operator=(const shared_ptr<_Tp1>& __r) // never throws
    01017         {
    01018       this->__shared_ptr<_Tp>::operator=(__r);
    01019       return *this;
    01020     }
    01021
    01022       template<typename _Tp1>
    01023         shared_ptr&
    01024         operator=(std::auto_ptr<_Tp1>& __r)
    01025         {
    01026       this->__shared_ptr<_Tp>::operator=(__r);
    01027       return *this;
    01028     }
    01029     };
    01030
    01031   template<typename _Tp, typename _Tp1>
    01032     shared_ptr<_Tp>
    01033     static_pointer_cast(const shared_ptr<_Tp1>& __r)
    01034     { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
    01035
    01036   template<typename _Tp, typename _Tp1>
    01037     shared_ptr<_Tp>
    01038     const_pointer_cast(const shared_ptr<_Tp1>& __r)
    01039     { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
    01040
    01041   template<typename _Tp, typename _Tp1>
    01042     shared_ptr<_Tp>
    01043     dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
    01044     { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
    01045
    01046
    01047   // The actual TR1 weak_ptr, with forwarding constructors and
    01048   // assignment operators.
    01049   template<typename _Tp>
    01050     class weak_ptr
    01051     : public __weak_ptr<_Tp>
    01052     {
    01053     public:
    01054       weak_ptr()
    01055       : __weak_ptr<_Tp>() { }
    01056
    01057       template<typename _Tp1>
    01058         weak_ptr(const weak_ptr<_Tp1>& __r)
    01059     : __weak_ptr<_Tp>(__r) { }
    01060
    01061       template<typename _Tp1>
    01062         weak_ptr(const shared_ptr<_Tp1>& __r)
    01063     : __weak_ptr<_Tp>(__r) { }
    01064
    01065       template<typename _Tp1>
    01066         weak_ptr&
    01067         operator=(const weak_ptr<_Tp1>& __r) // never throws
    01068         {
    01069       this->__weak_ptr<_Tp>::operator=(__r);
    01070       return *this;
    01071     }
    01072
    01073       template<typename _Tp1>
    01074         weak_ptr&
    01075         operator=(const shared_ptr<_Tp1>& __r) // never throws
    01076         {
    01077       this->__weak_ptr<_Tp>::operator=(__r);
    01078       return *this;
    01079     }
    01080
    01081       shared_ptr<_Tp>
    01082       lock() const // never throws
    01083       {
    01084 #ifdef __GTHREADS
    01085     if (this->expired())
    01086       return shared_ptr<_Tp>();
    01087
    01088     try
    01089       {
    01090         return shared_ptr<_Tp>(*this);
    01091       }
    01092     catch(const bad_weak_ptr&)
    01093       {
    01094         return shared_ptr<_Tp>();
    01095       }
    01096 #else
    01097     return this->expired() ? shared_ptr<_Tp>()
    01098                            : shared_ptr<_Tp>(*this);
    01099 #endif
    01100       }
    01101     };
    01102
    01103
    01104   template<typename _Tp>
    01105     class enable_shared_from_this
    01106     {
    01107     protected:
    01108       enable_shared_from_this() { }
    01109
    01110       enable_shared_from_this(const enable_shared_from_this&) { }
    01111
    01112       enable_shared_from_this&
    01113       operator=(const enable_shared_from_this&)
    01114       { return *this; }
    01115
    01116       ~enable_shared_from_this() { }
    01117
    01118     public:
    01119       shared_ptr<_Tp>
    01120       shared_from_this()
    01121       { return shared_ptr<_Tp>(this->_M_weak_this); }
    01122
    01123       shared_ptr<const _Tp>
    01124       shared_from_this() const
    01125       { return shared_ptr<const _Tp>(this->_M_weak_this); }
    01126
    01127     private:
    01128       template<typename _Tp1>
    01129         void
    01130         _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
    01131         { _M_weak_this._M_assign(__p, __n); }
    01132
    01133       template<typename _Tp1>
    01134         friend void
    01135         __enable_shared_from_this_helper(const __shared_count<>& __pn,
    01136                      const enable_shared_from_this* __pe,
    01137                      const _Tp1* __px)
    01138         {
    01139       if (__pe != 0)
    01140         __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
    01141     }
    01142
    01143       mutable weak_ptr<_Tp>  _M_weak_this;
    01144     };
    01145
    01146 _GLIBCXX_END_NAMESPACE
    01147 } // namespace std
    01148
    01149 #endif