libstdc++
shared_ptr.h
Go to the documentation of this file.
00001 // shared_ptr and weak_ptr implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2007-2015 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 // GCC Note: Based on files from version 1.32.0 of the Boost library.
00026 
00027 //  shared_count.hpp
00028 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
00029 
00030 //  shared_ptr.hpp
00031 //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
00032 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
00033 
00034 //  weak_ptr.hpp
00035 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
00036 
00037 //  enable_shared_from_this.hpp
00038 //  Copyright (C) 2002 Peter Dimov
00039 
00040 // Distributed under the Boost Software License, Version 1.0. (See
00041 // accompanying file LICENSE_1_0.txt or copy at
00042 // http://www.boost.org/LICENSE_1_0.txt)
00043 
00044 /** @file bits/shared_ptr.h
00045  *  This is an internal header file, included by other library headers.
00046  *  Do not attempt to use it directly. @headername{memory}
00047  */
00048 
00049 #ifndef _SHARED_PTR_H
00050 #define _SHARED_PTR_H 1
00051 
00052 #include <bits/shared_ptr_base.h>
00053 
00054 namespace std _GLIBCXX_VISIBILITY(default)
00055 {
00056 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00057 
00058   /**
00059    * @addtogroup pointer_abstractions
00060    * @{
00061    */
00062 
00063   /// 20.7.2.2.11 shared_ptr I/O
00064   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
00065     inline std::basic_ostream<_Ch, _Tr>&
00066     operator<<(std::basic_ostream<_Ch, _Tr>& __os,
00067                const __shared_ptr<_Tp, _Lp>& __p)
00068     {
00069       __os << __p.get();
00070       return __os;
00071     }
00072 
00073   /// 20.7.2.2.10 shared_ptr get_deleter
00074   template<typename _Del, typename _Tp, _Lock_policy _Lp>
00075     inline _Del*
00076     get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
00077     {
00078 #if __cpp_rtti
00079       return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
00080 #else
00081       return 0;
00082 #endif
00083     }
00084 
00085 
00086   /**
00087    *  @brief  A smart pointer with reference-counted copy semantics.
00088    *
00089    *  The object pointed to is deleted when the last shared_ptr pointing to
00090    *  it is destroyed or reset.
00091   */
00092   template<typename _Tp>
00093     class shared_ptr : public __shared_ptr<_Tp>
00094     {
00095       template<typename _Ptr>
00096         using _Convertible
00097           = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type;
00098 
00099     public:
00100       /**
00101        *  @brief  Construct an empty %shared_ptr.
00102        *  @post   use_count()==0 && get()==0
00103        */
00104       constexpr shared_ptr() noexcept
00105       : __shared_ptr<_Tp>() { }
00106 
00107       shared_ptr(const shared_ptr&) noexcept = default;
00108 
00109       /**
00110        *  @brief  Construct a %shared_ptr that owns the pointer @a __p.
00111        *  @param  __p  A pointer that is convertible to element_type*.
00112        *  @post   use_count() == 1 && get() == __p
00113        *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
00114        */
00115       template<typename _Tp1>
00116         explicit shared_ptr(_Tp1* __p)
00117         : __shared_ptr<_Tp>(__p) { }
00118 
00119       /**
00120        *  @brief  Construct a %shared_ptr that owns the pointer @a __p
00121        *          and the deleter @a __d.
00122        *  @param  __p  A pointer.
00123        *  @param  __d  A deleter.
00124        *  @post   use_count() == 1 && get() == __p
00125        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
00126        *
00127        *  Requirements: _Deleter's copy constructor and destructor must
00128        *  not throw
00129        *
00130        *  __shared_ptr will release __p by calling __d(__p)
00131        */
00132       template<typename _Tp1, typename _Deleter>
00133         shared_ptr(_Tp1* __p, _Deleter __d)
00134         : __shared_ptr<_Tp>(__p, __d) { }
00135 
00136       /**
00137        *  @brief  Construct a %shared_ptr that owns a null pointer
00138        *          and the deleter @a __d.
00139        *  @param  __p  A null pointer constant.
00140        *  @param  __d  A deleter.
00141        *  @post   use_count() == 1 && get() == __p
00142        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
00143        *
00144        *  Requirements: _Deleter's copy constructor and destructor must
00145        *  not throw
00146        *
00147        *  The last owner will call __d(__p)
00148        */
00149       template<typename _Deleter>
00150         shared_ptr(nullptr_t __p, _Deleter __d)
00151         : __shared_ptr<_Tp>(__p, __d) { }
00152 
00153       /**
00154        *  @brief  Construct a %shared_ptr that owns the pointer @a __p
00155        *          and the deleter @a __d.
00156        *  @param  __p  A pointer.
00157        *  @param  __d  A deleter.
00158        *  @param  __a  An allocator.
00159        *  @post   use_count() == 1 && get() == __p
00160        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
00161        *
00162        *  Requirements: _Deleter's copy constructor and destructor must
00163        *  not throw _Alloc's copy constructor and destructor must not
00164        *  throw.
00165        *
00166        *  __shared_ptr will release __p by calling __d(__p)
00167        */
00168       template<typename _Tp1, typename _Deleter, typename _Alloc>
00169         shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
00170         : __shared_ptr<_Tp>(__p, __d, std::move(__a)) { }
00171 
00172       /**
00173        *  @brief  Construct a %shared_ptr that owns a null pointer
00174        *          and the deleter @a __d.
00175        *  @param  __p  A null pointer constant.
00176        *  @param  __d  A deleter.
00177        *  @param  __a  An allocator.
00178        *  @post   use_count() == 1 && get() == __p
00179        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
00180        *
00181        *  Requirements: _Deleter's copy constructor and destructor must
00182        *  not throw _Alloc's copy constructor and destructor must not
00183        *  throw.
00184        *
00185        *  The last owner will call __d(__p)
00186        */
00187       template<typename _Deleter, typename _Alloc>
00188         shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
00189         : __shared_ptr<_Tp>(__p, __d, std::move(__a)) { }
00190 
00191       // Aliasing constructor
00192 
00193       /**
00194        *  @brief  Constructs a %shared_ptr instance that stores @a __p
00195        *          and shares ownership with @a __r.
00196        *  @param  __r  A %shared_ptr.
00197        *  @param  __p  A pointer that will remain valid while @a *__r is valid.
00198        *  @post   get() == __p && use_count() == __r.use_count()
00199        *
00200        *  This can be used to construct a @c shared_ptr to a sub-object
00201        *  of an object managed by an existing @c shared_ptr.
00202        *
00203        * @code
00204        * shared_ptr< pair<int,int> > pii(new pair<int,int>());
00205        * shared_ptr<int> pi(pii, &pii->first);
00206        * assert(pii.use_count() == 2);
00207        * @endcode
00208        */
00209       template<typename _Tp1>
00210         shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p) noexcept
00211         : __shared_ptr<_Tp>(__r, __p) { }
00212 
00213       /**
00214        *  @brief  If @a __r is empty, constructs an empty %shared_ptr;
00215        *          otherwise construct a %shared_ptr that shares ownership
00216        *          with @a __r.
00217        *  @param  __r  A %shared_ptr.
00218        *  @post   get() == __r.get() && use_count() == __r.use_count()
00219        */
00220       template<typename _Tp1, typename = _Convertible<_Tp1*>>
00221         shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
00222         : __shared_ptr<_Tp>(__r) { }
00223 
00224       /**
00225        *  @brief  Move-constructs a %shared_ptr instance from @a __r.
00226        *  @param  __r  A %shared_ptr rvalue.
00227        *  @post   *this contains the old value of @a __r, @a __r is empty.
00228        */
00229       shared_ptr(shared_ptr&& __r) noexcept
00230       : __shared_ptr<_Tp>(std::move(__r)) { }
00231 
00232       /**
00233        *  @brief  Move-constructs a %shared_ptr instance from @a __r.
00234        *  @param  __r  A %shared_ptr rvalue.
00235        *  @post   *this contains the old value of @a __r, @a __r is empty.
00236        */
00237       template<typename _Tp1, typename = _Convertible<_Tp1*>>
00238         shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
00239         : __shared_ptr<_Tp>(std::move(__r)) { }
00240 
00241       /**
00242        *  @brief  Constructs a %shared_ptr that shares ownership with @a __r
00243        *          and stores a copy of the pointer stored in @a __r.
00244        *  @param  __r  A weak_ptr.
00245        *  @post   use_count() == __r.use_count()
00246        *  @throw  bad_weak_ptr when __r.expired(),
00247        *          in which case the constructor has no effect.
00248        */
00249       template<typename _Tp1>
00250         explicit shared_ptr(const weak_ptr<_Tp1>& __r)
00251         : __shared_ptr<_Tp>(__r) { }
00252 
00253 #if _GLIBCXX_USE_DEPRECATED
00254       template<typename _Tp1>
00255         shared_ptr(std::auto_ptr<_Tp1>&& __r);
00256 #endif
00257 
00258       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00259       // 2399. shared_ptr's constructor from unique_ptr should be constrained
00260       template<typename _Tp1, typename _Del, typename
00261                = _Convertible<typename unique_ptr<_Tp1, _Del>::pointer>>
00262         shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
00263         : __shared_ptr<_Tp>(std::move(__r)) { }
00264 
00265       /**
00266        *  @brief  Construct an empty %shared_ptr.
00267        *  @post   use_count() == 0 && get() == nullptr
00268        */
00269       constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
00270 
00271       shared_ptr& operator=(const shared_ptr&) noexcept = default;
00272 
00273       template<typename _Tp1>
00274         shared_ptr&
00275         operator=(const shared_ptr<_Tp1>& __r) noexcept
00276         {
00277           this->__shared_ptr<_Tp>::operator=(__r);
00278           return *this;
00279         }
00280 
00281 #if _GLIBCXX_USE_DEPRECATED
00282       template<typename _Tp1>
00283         shared_ptr&
00284         operator=(std::auto_ptr<_Tp1>&& __r)
00285         {
00286           this->__shared_ptr<_Tp>::operator=(std::move(__r));
00287           return *this;
00288         }
00289 #endif
00290 
00291       shared_ptr&
00292       operator=(shared_ptr&& __r) noexcept
00293       {
00294         this->__shared_ptr<_Tp>::operator=(std::move(__r));
00295         return *this;
00296       }
00297 
00298       template<class _Tp1>
00299         shared_ptr&
00300         operator=(shared_ptr<_Tp1>&& __r) noexcept
00301         {
00302           this->__shared_ptr<_Tp>::operator=(std::move(__r));
00303           return *this;
00304         }
00305 
00306       template<typename _Tp1, typename _Del>
00307         shared_ptr&
00308         operator=(std::unique_ptr<_Tp1, _Del>&& __r)
00309         {
00310           this->__shared_ptr<_Tp>::operator=(std::move(__r));
00311           return *this;
00312         }
00313 
00314     private:
00315       // This constructor is non-standard, it is used by allocate_shared.
00316       template<typename _Alloc, typename... _Args>
00317         shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
00318                    _Args&&... __args)
00319         : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
00320         { }
00321 
00322       template<typename _Tp1, typename _Alloc, typename... _Args>
00323         friend shared_ptr<_Tp1>
00324         allocate_shared(const _Alloc& __a, _Args&&... __args);
00325 
00326       // This constructor is non-standard, it is used by weak_ptr::lock().
00327       shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
00328       : __shared_ptr<_Tp>(__r, std::nothrow) { }
00329 
00330       friend class weak_ptr<_Tp>;
00331     };
00332 
00333   // 20.7.2.2.7 shared_ptr comparisons
00334   template<typename _Tp1, typename _Tp2>
00335     inline bool
00336     operator==(const shared_ptr<_Tp1>& __a,
00337                const shared_ptr<_Tp2>& __b) noexcept
00338     { return __a.get() == __b.get(); }
00339 
00340   template<typename _Tp>
00341     inline bool
00342     operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00343     { return !__a; }
00344 
00345   template<typename _Tp>
00346     inline bool
00347     operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00348     { return !__a; }
00349 
00350   template<typename _Tp1, typename _Tp2>
00351     inline bool
00352     operator!=(const shared_ptr<_Tp1>& __a,
00353                const shared_ptr<_Tp2>& __b) noexcept
00354     { return __a.get() != __b.get(); }
00355 
00356   template<typename _Tp>
00357     inline bool
00358     operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00359     { return (bool)__a; }
00360 
00361   template<typename _Tp>
00362     inline bool
00363     operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00364     { return (bool)__a; }
00365 
00366   template<typename _Tp1, typename _Tp2>
00367     inline bool
00368     operator<(const shared_ptr<_Tp1>& __a,
00369               const shared_ptr<_Tp2>& __b) noexcept
00370     {
00371       typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
00372       return std::less<_CT>()(__a.get(), __b.get());
00373     }
00374 
00375   template<typename _Tp>
00376     inline bool
00377     operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00378     { return std::less<_Tp*>()(__a.get(), nullptr); }
00379 
00380   template<typename _Tp>
00381     inline bool
00382     operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00383     { return std::less<_Tp*>()(nullptr, __a.get()); }
00384 
00385   template<typename _Tp1, typename _Tp2>
00386     inline bool
00387     operator<=(const shared_ptr<_Tp1>& __a,
00388                const shared_ptr<_Tp2>& __b) noexcept
00389     { return !(__b < __a); }
00390 
00391   template<typename _Tp>
00392     inline bool
00393     operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00394     { return !(nullptr < __a); }
00395 
00396   template<typename _Tp>
00397     inline bool
00398     operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00399     { return !(__a < nullptr); }
00400 
00401   template<typename _Tp1, typename _Tp2>
00402     inline bool
00403     operator>(const shared_ptr<_Tp1>& __a,
00404               const shared_ptr<_Tp2>& __b) noexcept
00405     { return (__b < __a); }
00406 
00407   template<typename _Tp>
00408     inline bool
00409     operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00410     { return std::less<_Tp*>()(nullptr, __a.get()); }
00411 
00412   template<typename _Tp>
00413     inline bool
00414     operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00415     { return std::less<_Tp*>()(__a.get(), nullptr); }
00416 
00417   template<typename _Tp1, typename _Tp2>
00418     inline bool
00419     operator>=(const shared_ptr<_Tp1>& __a,
00420                const shared_ptr<_Tp2>& __b) noexcept
00421     { return !(__a < __b); }
00422 
00423   template<typename _Tp>
00424     inline bool
00425     operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00426     { return !(__a < nullptr); }
00427 
00428   template<typename _Tp>
00429     inline bool
00430     operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00431     { return !(nullptr < __a); }
00432 
00433   template<typename _Tp>
00434     struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>>
00435     { };
00436 
00437   // 20.7.2.2.8 shared_ptr specialized algorithms.
00438   template<typename _Tp>
00439     inline void
00440     swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
00441     { __a.swap(__b); }
00442 
00443   // 20.7.2.2.9 shared_ptr casts.
00444   template<typename _Tp, typename _Tp1>
00445     inline shared_ptr<_Tp>
00446     static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
00447     { return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); }
00448 
00449   template<typename _Tp, typename _Tp1>
00450     inline shared_ptr<_Tp>
00451     const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
00452     { return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); }
00453 
00454   template<typename _Tp, typename _Tp1>
00455     inline shared_ptr<_Tp>
00456     dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
00457     {
00458       if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
00459         return shared_ptr<_Tp>(__r, __p);
00460       return shared_ptr<_Tp>();
00461     }
00462 
00463 
00464   /**
00465    *  @brief  A smart pointer with weak semantics.
00466    *
00467    *  With forwarding constructors and assignment operators.
00468    */
00469   template<typename _Tp>
00470     class weak_ptr : public __weak_ptr<_Tp>
00471     {
00472       template<typename _Ptr>
00473         using _Convertible
00474           = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type;
00475 
00476     public:
00477       constexpr weak_ptr() noexcept = default;
00478 
00479       template<typename _Tp1, typename = _Convertible<_Tp1*>>
00480         weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
00481         : __weak_ptr<_Tp>(__r) { }
00482 
00483       weak_ptr(const weak_ptr&) noexcept = default;
00484 
00485       template<typename _Tp1, typename = _Convertible<_Tp1*>>
00486         weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
00487         : __weak_ptr<_Tp>(__r) { }
00488 
00489       weak_ptr(weak_ptr&&) noexcept = default;
00490 
00491       template<typename _Tp1, typename = _Convertible<_Tp1*>>
00492         weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
00493         : __weak_ptr<_Tp>(std::move(__r)) { }
00494 
00495       weak_ptr&
00496       operator=(const weak_ptr& __r) noexcept = default;
00497 
00498       template<typename _Tp1>
00499         weak_ptr&
00500         operator=(const weak_ptr<_Tp1>& __r) noexcept
00501         {
00502           this->__weak_ptr<_Tp>::operator=(__r);
00503           return *this;
00504         }
00505 
00506       template<typename _Tp1>
00507         weak_ptr&
00508         operator=(const shared_ptr<_Tp1>& __r) noexcept
00509         {
00510           this->__weak_ptr<_Tp>::operator=(__r);
00511           return *this;
00512         }
00513 
00514       weak_ptr&
00515       operator=(weak_ptr&& __r) noexcept = default;
00516 
00517       template<typename _Tp1>
00518         weak_ptr&
00519         operator=(weak_ptr<_Tp1>&& __r) noexcept
00520         {
00521           this->__weak_ptr<_Tp>::operator=(std::move(__r));
00522           return *this;
00523         }
00524 
00525       shared_ptr<_Tp>
00526       lock() const noexcept
00527       { return shared_ptr<_Tp>(*this, std::nothrow); }
00528     };
00529 
00530   // 20.7.2.3.6 weak_ptr specialized algorithms.
00531   template<typename _Tp>
00532     inline void
00533     swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
00534     { __a.swap(__b); }
00535 
00536 
00537   /// Primary template owner_less
00538   template<typename _Tp>
00539     struct owner_less;
00540 
00541   /// Partial specialization of owner_less for shared_ptr.
00542   template<typename _Tp>
00543     struct owner_less<shared_ptr<_Tp>>
00544     : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
00545     { };
00546 
00547   /// Partial specialization of owner_less for weak_ptr.
00548   template<typename _Tp>
00549     struct owner_less<weak_ptr<_Tp>>
00550     : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
00551     { };
00552 
00553   /**
00554    *  @brief Base class allowing use of member function shared_from_this.
00555    */
00556   template<typename _Tp>
00557     class enable_shared_from_this
00558     {
00559     protected:
00560       constexpr enable_shared_from_this() noexcept { }
00561 
00562       enable_shared_from_this(const enable_shared_from_this&) noexcept { }
00563 
00564       enable_shared_from_this&
00565       operator=(const enable_shared_from_this&) noexcept
00566       { return *this; }
00567 
00568       ~enable_shared_from_this() { }
00569 
00570     public:
00571       shared_ptr<_Tp>
00572       shared_from_this()
00573       { return shared_ptr<_Tp>(this->_M_weak_this); }
00574 
00575       shared_ptr<const _Tp>
00576       shared_from_this() const
00577       { return shared_ptr<const _Tp>(this->_M_weak_this); }
00578 
00579     private:
00580       template<typename _Tp1>
00581         void
00582         _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
00583         { _M_weak_this._M_assign(__p, __n); }
00584 
00585       template<typename _Tp1, typename _Tp2>
00586         friend void
00587         __enable_shared_from_this_helper(const __shared_count<>&,
00588                                          const enable_shared_from_this<_Tp1>*,
00589                                          const _Tp2*) noexcept;
00590 
00591       mutable weak_ptr<_Tp>  _M_weak_this;
00592     };
00593 
00594   template<typename _Tp1, typename _Tp2>
00595     inline void
00596     __enable_shared_from_this_helper(const __shared_count<>& __pn,
00597                                      const enable_shared_from_this<_Tp1>*
00598                                      __pe, const _Tp2* __px) noexcept
00599     {
00600       if (__pe != nullptr)
00601         __pe->_M_weak_assign(const_cast<_Tp2*>(__px), __pn);
00602     }
00603 
00604   /**
00605    *  @brief  Create an object that is owned by a shared_ptr.
00606    *  @param  __a     An allocator.
00607    *  @param  __args  Arguments for the @a _Tp object's constructor.
00608    *  @return A shared_ptr that owns the newly created object.
00609    *  @throw  An exception thrown from @a _Alloc::allocate or from the
00610    *          constructor of @a _Tp.
00611    *
00612    *  A copy of @a __a will be used to allocate memory for the shared_ptr
00613    *  and the new object.
00614    */
00615   template<typename _Tp, typename _Alloc, typename... _Args>
00616     inline shared_ptr<_Tp>
00617     allocate_shared(const _Alloc& __a, _Args&&... __args)
00618     {
00619       return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a,
00620                              std::forward<_Args>(__args)...);
00621     }
00622 
00623   /**
00624    *  @brief  Create an object that is owned by a shared_ptr.
00625    *  @param  __args  Arguments for the @a _Tp object's constructor.
00626    *  @return A shared_ptr that owns the newly created object.
00627    *  @throw  std::bad_alloc, or an exception thrown from the
00628    *          constructor of @a _Tp.
00629    */
00630   template<typename _Tp, typename... _Args>
00631     inline shared_ptr<_Tp>
00632     make_shared(_Args&&... __args)
00633     {
00634       typedef typename std::remove_const<_Tp>::type _Tp_nc;
00635       return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
00636                                        std::forward<_Args>(__args)...);
00637     }
00638 
00639   /// std::hash specialization for shared_ptr.
00640   template<typename _Tp>
00641     struct hash<shared_ptr<_Tp>>
00642     : public __hash_base<size_t, shared_ptr<_Tp>>
00643     {
00644       size_t
00645       operator()(const shared_ptr<_Tp>& __s) const noexcept
00646       { return std::hash<_Tp*>()(__s.get()); }
00647     };
00648 
00649   // @} group pointer_abstractions
00650 
00651 _GLIBCXX_END_NAMESPACE_VERSION
00652 } // namespace
00653 
00654 #endif // _SHARED_PTR_H