# boost_shared_ptr.h

Go to the documentation of this file.

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