libstdc++
shared_ptr_base.h
Go to the documentation of this file.
00001 // shared_ptr and weak_ptr implementation details -*- C++ -*-
00002 
00003 // Copyright (C) 2007-2013 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_base.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_BASE_H
00050 #define _SHARED_PTR_BASE_H 1
00051 
00052 namespace std _GLIBCXX_VISIBILITY(default)
00053 {
00054 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00055 
00056 #if _GLIBCXX_USE_DEPRECATED
00057   template<typename> class auto_ptr;
00058 #endif
00059 
00060  /**
00061    *  @brief  Exception possibly thrown by @c shared_ptr.
00062    *  @ingroup exceptions
00063    */
00064   class bad_weak_ptr : public std::exception
00065   {
00066   public:
00067     virtual char const*
00068     what() const noexcept;
00069 
00070     virtual ~bad_weak_ptr() noexcept;    
00071   };
00072 
00073   // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
00074   inline void
00075   __throw_bad_weak_ptr()
00076   { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
00077 
00078   using __gnu_cxx::_Lock_policy;
00079   using __gnu_cxx::__default_lock_policy;
00080   using __gnu_cxx::_S_single;
00081   using __gnu_cxx::_S_mutex;
00082   using __gnu_cxx::_S_atomic;
00083 
00084   // Empty helper class except when the template argument is _S_mutex.
00085   template<_Lock_policy _Lp>
00086     class _Mutex_base
00087     {
00088     protected:
00089       // The atomic policy uses fully-fenced builtins, single doesn't care.
00090       enum { _S_need_barriers = 0 };
00091     };
00092 
00093   template<>
00094     class _Mutex_base<_S_mutex>
00095     : public __gnu_cxx::__mutex
00096     {
00097     protected:
00098       // This policy is used when atomic builtins are not available.
00099       // The replacement atomic operations might not have the necessary
00100       // memory barriers.
00101       enum { _S_need_barriers = 1 };
00102     };
00103 
00104   template<_Lock_policy _Lp = __default_lock_policy>
00105     class _Sp_counted_base
00106     : public _Mutex_base<_Lp>
00107     {
00108     public:  
00109       _Sp_counted_base() noexcept
00110       : _M_use_count(1), _M_weak_count(1) { }
00111       
00112       virtual
00113       ~_Sp_counted_base() noexcept
00114       { }
00115   
00116       // Called when _M_use_count drops to zero, to release the resources
00117       // managed by *this.
00118       virtual void
00119       _M_dispose() noexcept = 0;
00120       
00121       // Called when _M_weak_count drops to zero.
00122       virtual void
00123       _M_destroy() noexcept
00124       { delete this; }
00125       
00126       virtual void*
00127       _M_get_deleter(const std::type_info&) = 0;
00128 
00129       void
00130       _M_add_ref_copy()
00131       { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
00132   
00133       void
00134       _M_add_ref_lock();
00135       
00136       void
00137       _M_release() noexcept
00138       {
00139         // Be race-detector-friendly.  For more info see bits/c++config.
00140         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
00141     if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
00142       {
00143             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
00144         _M_dispose();
00145         // There must be a memory barrier between dispose() and destroy()
00146         // to ensure that the effects of dispose() are observed in the
00147         // thread that runs destroy().
00148         // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
00149         if (_Mutex_base<_Lp>::_S_need_barriers)
00150           {
00151             _GLIBCXX_READ_MEM_BARRIER;
00152             _GLIBCXX_WRITE_MEM_BARRIER;
00153           }
00154 
00155             // Be race-detector-friendly.  For more info see bits/c++config.
00156             _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
00157         if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
00158                                -1) == 1)
00159               {
00160                 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
00161             _M_destroy();
00162               }
00163       }
00164       }
00165   
00166       void
00167       _M_weak_add_ref() noexcept
00168       { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
00169 
00170       void
00171       _M_weak_release() noexcept
00172       {
00173         // Be race-detector-friendly. For more info see bits/c++config.
00174         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
00175     if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
00176       {
00177             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
00178         if (_Mutex_base<_Lp>::_S_need_barriers)
00179           {
00180             // See _M_release(),
00181             // destroy() must observe results of dispose()
00182             _GLIBCXX_READ_MEM_BARRIER;
00183             _GLIBCXX_WRITE_MEM_BARRIER;
00184           }
00185         _M_destroy();
00186       }
00187       }
00188   
00189       long
00190       _M_get_use_count() const noexcept
00191       {
00192         // No memory barrier is used here so there is no synchronization
00193         // with other threads.
00194         return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
00195       }
00196 
00197     private:  
00198       _Sp_counted_base(_Sp_counted_base const&) = delete;
00199       _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
00200 
00201       _Atomic_word  _M_use_count;     // #shared
00202       _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
00203     };
00204 
00205   template<>
00206     inline void
00207     _Sp_counted_base<_S_single>::
00208     _M_add_ref_lock()
00209     {
00210       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
00211     {
00212       _M_use_count = 0;
00213       __throw_bad_weak_ptr();
00214     }
00215     }
00216 
00217   template<>
00218     inline void
00219     _Sp_counted_base<_S_mutex>::
00220     _M_add_ref_lock()
00221     {
00222       __gnu_cxx::__scoped_lock sentry(*this);
00223       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
00224     {
00225       _M_use_count = 0;
00226       __throw_bad_weak_ptr();
00227     }
00228     }
00229 
00230   template<> 
00231     inline void
00232     _Sp_counted_base<_S_atomic>::
00233     _M_add_ref_lock()
00234     {
00235       // Perform lock-free add-if-not-zero operation.
00236       _Atomic_word __count = _M_get_use_count();
00237       do
00238     {
00239       if (__count == 0)
00240         __throw_bad_weak_ptr();
00241       // Replace the current counter value with the old value + 1, as
00242       // long as it's not changed meanwhile. 
00243     }
00244       while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
00245                       true, __ATOMIC_ACQ_REL, 
00246                       __ATOMIC_RELAXED));
00247     }
00248 
00249 
00250   // Forward declarations.
00251   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
00252     class __shared_ptr;
00253 
00254   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
00255     class __weak_ptr;
00256 
00257   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
00258     class __enable_shared_from_this;
00259 
00260   template<typename _Tp>
00261     class shared_ptr;
00262 
00263   template<typename _Tp>
00264     class weak_ptr;
00265 
00266   template<typename _Tp>
00267     struct owner_less;
00268 
00269   template<typename _Tp>
00270     class enable_shared_from_this;
00271 
00272   template<_Lock_policy _Lp = __default_lock_policy>
00273     class __weak_count;
00274 
00275   template<_Lock_policy _Lp = __default_lock_policy>
00276     class __shared_count;
00277 
00278 
00279   // Counted ptr with no deleter or allocator support
00280   template<typename _Ptr, _Lock_policy _Lp>
00281     class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
00282     {
00283     public:
00284       explicit
00285       _Sp_counted_ptr(_Ptr __p)
00286       : _M_ptr(__p) { }
00287 
00288       virtual void
00289       _M_dispose() noexcept
00290       { delete _M_ptr; }
00291 
00292       virtual void
00293       _M_destroy() noexcept
00294       { delete this; }
00295 
00296       virtual void*
00297       _M_get_deleter(const std::type_info&)
00298       { return 0; }
00299 
00300       _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
00301       _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
00302 
00303     protected:
00304       _Ptr             _M_ptr;  // copy constructor must not throw
00305     };
00306 
00307   template<>
00308     inline void
00309     _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { }
00310 
00311   template<>
00312     inline void
00313     _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { }
00314 
00315   template<>
00316     inline void
00317     _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { }
00318 
00319   // Support for custom deleter and/or allocator
00320   template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
00321     class _Sp_counted_deleter final : public _Sp_counted_base<_Lp>
00322     {
00323       // Helper class that stores the Deleter and also acts as an allocator.
00324       // Used to dispose of the owned pointer and the internal refcount
00325       // Requires that copies of _Alloc can free each other's memory.
00326       struct _My_Deleter
00327       : public _Alloc           // copy constructor must not throw
00328       {
00329     _Deleter _M_del;        // copy constructor must not throw
00330     _My_Deleter(_Deleter __d, const _Alloc& __a)
00331     : _Alloc(__a), _M_del(__d) { }
00332       };
00333 
00334     public:
00335       // __d(__p) must not throw.
00336       _Sp_counted_deleter(_Ptr __p, _Deleter __d)
00337       : _M_ptr(__p), _M_del(__d, _Alloc()) { }
00338 
00339       // __d(__p) must not throw.
00340       _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a)
00341       : _M_ptr(__p), _M_del(__d, __a) { }
00342 
00343       ~_Sp_counted_deleter() noexcept { }
00344 
00345       virtual void
00346       _M_dispose() noexcept
00347       { _M_del._M_del(_M_ptr); }
00348 
00349       virtual void
00350       _M_destroy() noexcept
00351       {
00352     typedef typename allocator_traits<_Alloc>::template
00353       rebind_traits<_Sp_counted_deleter> _Alloc_traits;
00354     typename _Alloc_traits::allocator_type __a(_M_del);
00355     _Alloc_traits::destroy(__a, this);
00356     _Alloc_traits::deallocate(__a, this, 1);
00357       }
00358 
00359       virtual void*
00360       _M_get_deleter(const std::type_info& __ti)
00361       {
00362 #ifdef __GXX_RTTI
00363         return __ti == typeid(_Deleter) ? &_M_del._M_del : 0;
00364 #else
00365         return 0;
00366 #endif
00367       }
00368 
00369     protected:
00370       _Ptr             _M_ptr;  // copy constructor must not throw
00371       _My_Deleter      _M_del;  // copy constructor must not throw
00372     };
00373 
00374   // helpers for make_shared / allocate_shared
00375 
00376   struct _Sp_make_shared_tag { };
00377 
00378   template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
00379     class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
00380     {
00381       // Helper class that stores the pointer and also acts as an allocator.
00382       // Used to dispose of the owned pointer and the internal refcount
00383       // Requires that copies of _Alloc can free each other's memory.
00384       struct _Impl
00385       : public _Alloc           // copy constructor must not throw
00386       {
00387     _Impl(_Alloc __a) : _Alloc(__a), _M_ptr() { }
00388     _Tp* _M_ptr;
00389       };
00390 
00391     public:
00392       template<typename... _Args>
00393     _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
00394     : _M_impl(__a)
00395     {
00396       _M_impl._M_ptr = static_cast<_Tp*>(static_cast<void*>(&_M_storage));
00397       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00398       // 2070.  allocate_shared should use allocator_traits<A>::construct
00399       allocator_traits<_Alloc>::construct(__a, _M_impl._M_ptr,
00400           std::forward<_Args>(__args)...); // might throw
00401     }
00402 
00403       ~_Sp_counted_ptr_inplace() noexcept { }
00404 
00405       virtual void
00406       _M_dispose() noexcept
00407       { allocator_traits<_Alloc>::destroy(_M_impl, _M_impl._M_ptr); }
00408 
00409       // Override because the allocator needs to know the dynamic type
00410       virtual void
00411       _M_destroy() noexcept
00412       {
00413     typedef typename allocator_traits<_Alloc>::template
00414       rebind_traits<_Sp_counted_ptr_inplace> _Alloc_traits;
00415     typename _Alloc_traits::allocator_type __a(_M_impl);
00416     _Alloc_traits::destroy(__a, this);
00417     _Alloc_traits::deallocate(__a, this, 1);
00418       }
00419 
00420       // Sneaky trick so __shared_ptr can get the managed pointer
00421       virtual void*
00422       _M_get_deleter(const std::type_info& __ti) noexcept
00423       {
00424 #ifdef __GXX_RTTI
00425     return __ti == typeid(_Sp_make_shared_tag)
00426            ? static_cast<void*>(&_M_storage)
00427            : 0;
00428 #else
00429         return 0;
00430 #endif
00431       }
00432 
00433     private:
00434       _Impl _M_impl;
00435       typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type
00436     _M_storage;
00437     };
00438 
00439   template<_Lock_policy _Lp>
00440     class __shared_count
00441     {
00442     public:
00443       constexpr __shared_count() noexcept : _M_pi(0)
00444       { }
00445 
00446       template<typename _Ptr>
00447         explicit
00448     __shared_count(_Ptr __p) : _M_pi(0)
00449     {
00450       __try
00451         {
00452           _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
00453         }
00454       __catch(...)
00455         {
00456           delete __p;
00457           __throw_exception_again;
00458         }
00459     }
00460 
00461       template<typename _Ptr, typename _Deleter>
00462     __shared_count(_Ptr __p, _Deleter __d)
00463     : __shared_count(__p, std::move(__d), allocator<int>())
00464     { }
00465 
00466       template<typename _Ptr, typename _Deleter, typename _Alloc>
00467     __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
00468     {
00469       typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
00470       typedef typename allocator_traits<_Alloc>::template
00471         rebind_traits<_Sp_cd_type> _Alloc_traits;
00472       typename _Alloc_traits::allocator_type __a2(__a);
00473       _Sp_cd_type* __mem = 0;
00474       __try
00475         {
00476           __mem = _Alloc_traits::allocate(__a2, 1);
00477           _Alloc_traits::construct(__a2, __mem,
00478           __p, std::move(__d), std::move(__a));
00479           _M_pi = __mem;
00480         }
00481       __catch(...)
00482         {
00483           __d(__p); // Call _Deleter on __p.
00484           if (__mem)
00485             _Alloc_traits::deallocate(__a2, __mem, 1);
00486           __throw_exception_again;
00487         }
00488     }
00489 
00490       template<typename _Tp, typename _Alloc, typename... _Args>
00491     __shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a,
00492                _Args&&... __args)
00493     : _M_pi(0)
00494     {
00495       typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
00496       typedef typename allocator_traits<_Alloc>::template
00497         rebind_traits<_Sp_cp_type> _Alloc_traits;
00498       typename _Alloc_traits::allocator_type __a2(__a);
00499       _Sp_cp_type* __mem = _Alloc_traits::allocate(__a2, 1);
00500       __try
00501         {
00502           _Alloc_traits::construct(__a2, __mem, std::move(__a),
00503             std::forward<_Args>(__args)...);
00504           _M_pi = __mem;
00505         }
00506       __catch(...)
00507         {
00508           _Alloc_traits::deallocate(__a2, __mem, 1);
00509           __throw_exception_again;
00510         }
00511     }
00512 
00513 #if _GLIBCXX_USE_DEPRECATED
00514       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
00515       template<typename _Tp>
00516         explicit
00517     __shared_count(std::auto_ptr<_Tp>&& __r);
00518 #endif
00519 
00520       // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
00521       template<typename _Tp, typename _Del>
00522         explicit
00523     __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
00524     {
00525       using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
00526       using _Del2 = typename conditional<is_reference<_Del>::value,
00527           reference_wrapper<typename remove_reference<_Del>::type>,
00528           _Del>::type;
00529       using _Sp_cd_type
00530         = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
00531       using _Alloc = allocator<_Sp_cd_type>;
00532       using _Alloc_traits = allocator_traits<_Alloc>;
00533       _Alloc __a;
00534       _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
00535       _Alloc_traits::construct(__a, __mem, __r.release(),
00536                    __r.get_deleter());  // non-throwing
00537       _M_pi = __mem;
00538     }
00539 
00540       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
00541       explicit __shared_count(const __weak_count<_Lp>& __r);
00542 
00543       ~__shared_count() noexcept
00544       {
00545     if (_M_pi != nullptr)
00546       _M_pi->_M_release();
00547       }
00548 
00549       __shared_count(const __shared_count& __r) noexcept
00550       : _M_pi(__r._M_pi)
00551       {
00552     if (_M_pi != 0)
00553       _M_pi->_M_add_ref_copy();
00554       }
00555 
00556       __shared_count&
00557       operator=(const __shared_count& __r) noexcept
00558       {
00559     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00560     if (__tmp != _M_pi)
00561       {
00562         if (__tmp != 0)
00563           __tmp->_M_add_ref_copy();
00564         if (_M_pi != 0)
00565           _M_pi->_M_release();
00566         _M_pi = __tmp;
00567       }
00568     return *this;
00569       }
00570 
00571       void
00572       _M_swap(__shared_count& __r) noexcept
00573       {
00574     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00575     __r._M_pi = _M_pi;
00576     _M_pi = __tmp;
00577       }
00578 
00579       long
00580       _M_get_use_count() const noexcept
00581       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
00582 
00583       bool
00584       _M_unique() const noexcept
00585       { return this->_M_get_use_count() == 1; }
00586 
00587       void*
00588       _M_get_deleter(const std::type_info& __ti) const noexcept
00589       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
00590 
00591       bool
00592       _M_less(const __shared_count& __rhs) const noexcept
00593       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00594 
00595       bool
00596       _M_less(const __weak_count<_Lp>& __rhs) const noexcept
00597       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00598 
00599       // Friend function injected into enclosing namespace and found by ADL
00600       friend inline bool
00601       operator==(const __shared_count& __a, const __shared_count& __b) noexcept
00602       { return __a._M_pi == __b._M_pi; }
00603 
00604     private:
00605       friend class __weak_count<_Lp>;
00606 
00607       _Sp_counted_base<_Lp>*  _M_pi;
00608     };
00609 
00610 
00611   template<_Lock_policy _Lp>
00612     class __weak_count
00613     {
00614     public:
00615       constexpr __weak_count() noexcept : _M_pi(0)
00616       { }
00617 
00618       __weak_count(const __shared_count<_Lp>& __r) noexcept
00619       : _M_pi(__r._M_pi)
00620       {
00621     if (_M_pi != 0)
00622       _M_pi->_M_weak_add_ref();
00623       }
00624 
00625       __weak_count(const __weak_count<_Lp>& __r) noexcept
00626       : _M_pi(__r._M_pi)
00627       {
00628     if (_M_pi != 0)
00629       _M_pi->_M_weak_add_ref();
00630       }
00631 
00632       ~__weak_count() noexcept
00633       {
00634     if (_M_pi != 0)
00635       _M_pi->_M_weak_release();
00636       }
00637 
00638       __weak_count<_Lp>&
00639       operator=(const __shared_count<_Lp>& __r) noexcept
00640       {
00641     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00642     if (__tmp != 0)
00643       __tmp->_M_weak_add_ref();
00644     if (_M_pi != 0)
00645       _M_pi->_M_weak_release();
00646     _M_pi = __tmp;
00647     return *this;
00648       }
00649 
00650       __weak_count<_Lp>&
00651       operator=(const __weak_count<_Lp>& __r) noexcept
00652       {
00653     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00654     if (__tmp != 0)
00655       __tmp->_M_weak_add_ref();
00656     if (_M_pi != 0)
00657       _M_pi->_M_weak_release();
00658     _M_pi = __tmp;
00659     return *this;
00660       }
00661 
00662       void
00663       _M_swap(__weak_count<_Lp>& __r) noexcept
00664       {
00665     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00666     __r._M_pi = _M_pi;
00667     _M_pi = __tmp;
00668       }
00669 
00670       long
00671       _M_get_use_count() const noexcept
00672       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
00673 
00674       bool
00675       _M_less(const __weak_count& __rhs) const noexcept
00676       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00677 
00678       bool
00679       _M_less(const __shared_count<_Lp>& __rhs) const noexcept
00680       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00681 
00682       // Friend function injected into enclosing namespace and found by ADL
00683       friend inline bool
00684       operator==(const __weak_count& __a, const __weak_count& __b) noexcept
00685       { return __a._M_pi == __b._M_pi; }
00686 
00687     private:
00688       friend class __shared_count<_Lp>;
00689 
00690       _Sp_counted_base<_Lp>*  _M_pi;
00691     };
00692 
00693   // Now that __weak_count is defined we can define this constructor:
00694   template<_Lock_policy _Lp>
00695     inline __shared_count<_Lp>:: __shared_count(const __weak_count<_Lp>& __r)
00696     : _M_pi(__r._M_pi)
00697     {
00698       if (_M_pi != 0)
00699     _M_pi->_M_add_ref_lock();
00700       else
00701     __throw_bad_weak_ptr();
00702     }
00703 
00704 
00705   // Support for enable_shared_from_this.
00706 
00707   // Friend of __enable_shared_from_this.
00708   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
00709     void
00710     __enable_shared_from_this_helper(const __shared_count<_Lp>&,
00711                      const __enable_shared_from_this<_Tp1,
00712                      _Lp>*, const _Tp2*) noexcept;
00713 
00714   // Friend of enable_shared_from_this.
00715   template<typename _Tp1, typename _Tp2>
00716     void
00717     __enable_shared_from_this_helper(const __shared_count<>&,
00718                      const enable_shared_from_this<_Tp1>*,
00719                      const _Tp2*) noexcept;
00720 
00721   template<_Lock_policy _Lp>
00722     inline void
00723     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) noexcept
00724     { }
00725 
00726 
00727   template<typename _Tp, _Lock_policy _Lp>
00728     class __shared_ptr
00729     {
00730     public:
00731       typedef _Tp   element_type;
00732 
00733       constexpr __shared_ptr() noexcept
00734       : _M_ptr(0), _M_refcount()
00735       { }
00736 
00737       template<typename _Tp1>
00738     explicit __shared_ptr(_Tp1* __p)
00739         : _M_ptr(__p), _M_refcount(__p)
00740     {
00741       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00742       static_assert( sizeof(_Tp1) > 0, "incomplete type" );
00743       __enable_shared_from_this_helper(_M_refcount, __p, __p);
00744     }
00745 
00746       template<typename _Tp1, typename _Deleter>
00747     __shared_ptr(_Tp1* __p, _Deleter __d)
00748     : _M_ptr(__p), _M_refcount(__p, __d)
00749     {
00750       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00751       // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
00752       __enable_shared_from_this_helper(_M_refcount, __p, __p);
00753     }
00754 
00755       template<typename _Tp1, typename _Deleter, typename _Alloc>
00756     __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
00757     : _M_ptr(__p), _M_refcount(__p, __d, std::move(__a))
00758     {
00759       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00760       // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
00761       __enable_shared_from_this_helper(_M_refcount, __p, __p);
00762     }
00763 
00764       template<typename _Deleter>
00765     __shared_ptr(nullptr_t __p, _Deleter __d)
00766     : _M_ptr(0), _M_refcount(__p, __d)
00767     { }
00768 
00769       template<typename _Deleter, typename _Alloc>
00770         __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
00771     : _M_ptr(0), _M_refcount(__p, __d, std::move(__a))
00772     { }
00773 
00774       template<typename _Tp1>
00775     __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept
00776     : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
00777     { }
00778 
00779       __shared_ptr(const __shared_ptr&) noexcept = default;
00780       __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
00781       ~__shared_ptr() = default;
00782 
00783       template<typename _Tp1, typename = typename
00784            std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
00785     __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
00786     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
00787     { }
00788 
00789       __shared_ptr(__shared_ptr&& __r) noexcept
00790       : _M_ptr(__r._M_ptr), _M_refcount()
00791       {
00792     _M_refcount._M_swap(__r._M_refcount);
00793     __r._M_ptr = 0;
00794       }
00795 
00796       template<typename _Tp1, typename = typename
00797            std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
00798     __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
00799     : _M_ptr(__r._M_ptr), _M_refcount()
00800     {
00801       _M_refcount._M_swap(__r._M_refcount);
00802       __r._M_ptr = 0;
00803     }
00804 
00805       template<typename _Tp1>
00806     explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
00807     : _M_refcount(__r._M_refcount) // may throw
00808     {
00809       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00810 
00811       // It is now safe to copy __r._M_ptr, as
00812       // _M_refcount(__r._M_refcount) did not throw.
00813       _M_ptr = __r._M_ptr;
00814     }
00815 
00816       // If an exception is thrown this constructor has no effect.
00817       template<typename _Tp1, typename _Del>
00818     __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
00819     : _M_ptr(__r.get()), _M_refcount()
00820     {
00821       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00822       auto __tmp = __r.get();
00823       _M_refcount = __shared_count<_Lp>(std::move(__r));
00824       __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
00825     }
00826 
00827 #if _GLIBCXX_USE_DEPRECATED
00828       // Postcondition: use_count() == 1 and __r.get() == 0
00829       template<typename _Tp1>
00830     __shared_ptr(std::auto_ptr<_Tp1>&& __r);
00831 #endif
00832 
00833       /* TODO: use delegating constructor */
00834       constexpr __shared_ptr(nullptr_t) noexcept
00835       : _M_ptr(0), _M_refcount()
00836       { }
00837 
00838       template<typename _Tp1>
00839     __shared_ptr&
00840     operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
00841     {
00842       _M_ptr = __r._M_ptr;
00843       _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
00844       return *this;
00845     }
00846 
00847 #if _GLIBCXX_USE_DEPRECATED
00848       template<typename _Tp1>
00849     __shared_ptr&
00850     operator=(std::auto_ptr<_Tp1>&& __r)
00851     {
00852       __shared_ptr(std::move(__r)).swap(*this);
00853       return *this;
00854     }
00855 #endif
00856 
00857       __shared_ptr&
00858       operator=(__shared_ptr&& __r) noexcept
00859       {
00860     __shared_ptr(std::move(__r)).swap(*this);
00861     return *this;
00862       }
00863 
00864       template<class _Tp1>
00865     __shared_ptr&
00866     operator=(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
00867     {
00868       __shared_ptr(std::move(__r)).swap(*this);
00869       return *this;
00870     }
00871 
00872       template<typename _Tp1, typename _Del>
00873     __shared_ptr&
00874     operator=(std::unique_ptr<_Tp1, _Del>&& __r)
00875     {
00876       __shared_ptr(std::move(__r)).swap(*this);
00877       return *this;
00878     }
00879 
00880       void
00881       reset() noexcept
00882       { __shared_ptr().swap(*this); }
00883 
00884       template<typename _Tp1>
00885     void
00886     reset(_Tp1* __p) // _Tp1 must be complete.
00887     {
00888       // Catch self-reset errors.
00889       _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
00890       __shared_ptr(__p).swap(*this);
00891     }
00892 
00893       template<typename _Tp1, typename _Deleter>
00894     void
00895     reset(_Tp1* __p, _Deleter __d)
00896     { __shared_ptr(__p, __d).swap(*this); }
00897 
00898       template<typename _Tp1, typename _Deleter, typename _Alloc>
00899     void
00900         reset(_Tp1* __p, _Deleter __d, _Alloc __a)
00901         { __shared_ptr(__p, __d, std::move(__a)).swap(*this); }
00902 
00903       // Allow class instantiation when _Tp is [cv-qual] void.
00904       typename std::add_lvalue_reference<_Tp>::type
00905       operator*() const noexcept
00906       {
00907     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00908     return *_M_ptr;
00909       }
00910 
00911       _Tp*
00912       operator->() const noexcept
00913       {
00914     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00915     return _M_ptr;
00916       }
00917 
00918       _Tp*
00919       get() const noexcept
00920       { return _M_ptr; }
00921 
00922       explicit operator bool() const // never throws
00923       { return _M_ptr == 0 ? false : true; }
00924 
00925       bool
00926       unique() const noexcept
00927       { return _M_refcount._M_unique(); }
00928 
00929       long
00930       use_count() const noexcept
00931       { return _M_refcount._M_get_use_count(); }
00932 
00933       void
00934       swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
00935       {
00936     std::swap(_M_ptr, __other._M_ptr);
00937     _M_refcount._M_swap(__other._M_refcount);
00938       }
00939 
00940       template<typename _Tp1>
00941     bool
00942     owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const
00943     { return _M_refcount._M_less(__rhs._M_refcount); }
00944 
00945       template<typename _Tp1>
00946     bool
00947     owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const
00948     { return _M_refcount._M_less(__rhs._M_refcount); }
00949 
00950 #ifdef __GXX_RTTI
00951     protected:
00952       // This constructor is non-standard, it is used by allocate_shared.
00953       template<typename _Alloc, typename... _Args>
00954     __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
00955              _Args&&... __args)
00956     : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
00957                 std::forward<_Args>(__args)...)
00958     {
00959       // _M_ptr needs to point to the newly constructed object.
00960       // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
00961       void* __p = _M_refcount._M_get_deleter(typeid(__tag));
00962       _M_ptr = static_cast<_Tp*>(__p);
00963       __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
00964     }
00965 #else
00966       template<typename _Alloc>
00967         struct _Deleter
00968         {
00969           void operator()(_Tp* __ptr)
00970           {
00971         typedef allocator_traits<_Alloc> _Alloc_traits;
00972         _Alloc_traits::destroy(_M_alloc, __ptr);
00973         _Alloc_traits::deallocate(_M_alloc, __ptr, 1);
00974           }
00975           _Alloc _M_alloc;
00976         };
00977 
00978       template<typename _Alloc, typename... _Args>
00979     __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
00980              _Args&&... __args)
00981     : _M_ptr(), _M_refcount()
00982         {
00983       typedef typename _Alloc::template rebind<_Tp>::other _Alloc2;
00984           _Deleter<_Alloc2> __del = { _Alloc2(__a) };
00985       typedef allocator_traits<_Alloc2> __traits;
00986           _M_ptr = __traits::allocate(__del._M_alloc, 1);
00987       __try
00988         {
00989           // _GLIBCXX_RESOLVE_LIB_DEFECTS
00990           // 2070. allocate_shared should use allocator_traits<A>::construct
00991           __traits::construct(__del._M_alloc, _M_ptr,
00992                           std::forward<_Args>(__args)...);
00993         }
00994       __catch(...)
00995         {
00996           __traits::deallocate(__del._M_alloc, _M_ptr, 1);
00997           __throw_exception_again;
00998         }
00999           __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);
01000           _M_refcount._M_swap(__count);
01001       __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
01002         }
01003 #endif
01004 
01005       template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
01006            typename... _Args>
01007     friend __shared_ptr<_Tp1, _Lp1>
01008     __allocate_shared(const _Alloc& __a, _Args&&... __args);
01009 
01010     private:
01011       void*
01012       _M_get_deleter(const std::type_info& __ti) const noexcept
01013       { return _M_refcount._M_get_deleter(__ti); }
01014 
01015       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
01016       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
01017 
01018       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
01019     friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
01020 
01021       _Tp*         _M_ptr;         // Contained pointer.
01022       __shared_count<_Lp>  _M_refcount;    // Reference counter.
01023     };
01024 
01025 
01026   // 20.7.2.2.7 shared_ptr comparisons
01027   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01028     inline bool
01029     operator==(const __shared_ptr<_Tp1, _Lp>& __a,
01030            const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01031     { return __a.get() == __b.get(); }
01032 
01033   template<typename _Tp, _Lock_policy _Lp>
01034     inline bool
01035     operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01036     { return !__a; }
01037 
01038   template<typename _Tp, _Lock_policy _Lp>
01039     inline bool
01040     operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01041     { return !__a; }
01042 
01043   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01044     inline bool
01045     operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
01046            const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01047     { return __a.get() != __b.get(); }
01048 
01049   template<typename _Tp, _Lock_policy _Lp>
01050     inline bool
01051     operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01052     { return (bool)__a; }
01053 
01054   template<typename _Tp, _Lock_policy _Lp>
01055     inline bool
01056     operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01057     { return (bool)__a; }
01058 
01059   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01060     inline bool
01061     operator<(const __shared_ptr<_Tp1, _Lp>& __a,
01062           const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01063     {
01064       typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
01065       return std::less<_CT>()(__a.get(), __b.get());
01066     }
01067 
01068   template<typename _Tp, _Lock_policy _Lp>
01069     inline bool
01070     operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01071     { return std::less<_Tp*>()(__a.get(), nullptr); }
01072 
01073   template<typename _Tp, _Lock_policy _Lp>
01074     inline bool
01075     operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01076     { return std::less<_Tp*>()(nullptr, __a.get()); }
01077 
01078   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01079     inline bool
01080     operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
01081            const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01082     { return !(__b < __a); }
01083 
01084   template<typename _Tp, _Lock_policy _Lp>
01085     inline bool
01086     operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01087     { return !(nullptr < __a); }
01088 
01089   template<typename _Tp, _Lock_policy _Lp>
01090     inline bool
01091     operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01092     { return !(__a < nullptr); }
01093 
01094   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01095     inline bool
01096     operator>(const __shared_ptr<_Tp1, _Lp>& __a,
01097           const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01098     { return (__b < __a); }
01099 
01100   template<typename _Tp, _Lock_policy _Lp>
01101     inline bool
01102     operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01103     { return std::less<_Tp*>()(nullptr, __a.get()); }
01104 
01105   template<typename _Tp, _Lock_policy _Lp>
01106     inline bool
01107     operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01108     { return std::less<_Tp*>()(__a.get(), nullptr); }
01109 
01110   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01111     inline bool
01112     operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
01113            const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01114     { return !(__a < __b); }
01115 
01116   template<typename _Tp, _Lock_policy _Lp>
01117     inline bool
01118     operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01119     { return !(__a < nullptr); }
01120 
01121   template<typename _Tp, _Lock_policy _Lp>
01122     inline bool
01123     operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01124     { return !(nullptr < __a); }
01125 
01126   template<typename _Sp>
01127     struct _Sp_less : public binary_function<_Sp, _Sp, bool>
01128     {
01129       bool
01130       operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept
01131       {
01132     typedef typename _Sp::element_type element_type;
01133     return std::less<element_type*>()(__lhs.get(), __rhs.get());
01134       }
01135     };
01136 
01137   template<typename _Tp, _Lock_policy _Lp>
01138     struct less<__shared_ptr<_Tp, _Lp>>
01139     : public _Sp_less<__shared_ptr<_Tp, _Lp>>
01140     { };
01141 
01142   // 2.2.3.8 shared_ptr specialized algorithms.
01143   template<typename _Tp, _Lock_policy _Lp>
01144     inline void
01145     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
01146     { __a.swap(__b); }
01147 
01148   // 2.2.3.9 shared_ptr casts
01149 
01150   // The seemingly equivalent code:
01151   // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
01152   // will eventually result in undefined behaviour, attempting to
01153   // delete the same object twice.
01154   /// static_pointer_cast
01155   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
01156     inline __shared_ptr<_Tp, _Lp>
01157     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
01158     { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
01159 
01160   // The seemingly equivalent code:
01161   // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
01162   // will eventually result in undefined behaviour, attempting to
01163   // delete the same object twice.
01164   /// const_pointer_cast
01165   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
01166     inline __shared_ptr<_Tp, _Lp>
01167     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
01168     { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
01169 
01170   // The seemingly equivalent code:
01171   // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
01172   // will eventually result in undefined behaviour, attempting to
01173   // delete the same object twice.
01174   /// dynamic_pointer_cast
01175   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
01176     inline __shared_ptr<_Tp, _Lp>
01177     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
01178     {
01179       if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
01180     return __shared_ptr<_Tp, _Lp>(__r, __p);
01181       return __shared_ptr<_Tp, _Lp>();
01182     }
01183 
01184 
01185   template<typename _Tp, _Lock_policy _Lp>
01186     class __weak_ptr
01187     {
01188     public:
01189       typedef _Tp element_type;
01190 
01191       constexpr __weak_ptr() noexcept
01192       : _M_ptr(0), _M_refcount()
01193       { }
01194 
01195       __weak_ptr(const __weak_ptr&) noexcept = default;
01196       __weak_ptr& operator=(const __weak_ptr&) noexcept = default;
01197       ~__weak_ptr() = default;
01198 
01199       // The "obvious" converting constructor implementation:
01200       //
01201       //  template<typename _Tp1>
01202       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
01203       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
01204       //    { }
01205       //
01206       // has a serious problem.
01207       //
01208       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
01209       //  conversion may require access to *__r._M_ptr (virtual inheritance).
01210       //
01211       // It is not possible to avoid spurious access violations since
01212       // in multithreaded programs __r._M_ptr may be invalidated at any point.
01213       template<typename _Tp1, typename = typename
01214            std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
01215     __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
01216     : _M_refcount(__r._M_refcount)
01217         { _M_ptr = __r.lock().get(); }
01218 
01219       template<typename _Tp1, typename = typename
01220            std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
01221     __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
01222     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
01223     { }
01224 
01225       template<typename _Tp1>
01226     __weak_ptr&
01227     operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
01228     {
01229       _M_ptr = __r.lock().get();
01230       _M_refcount = __r._M_refcount;
01231       return *this;
01232     }
01233 
01234       template<typename _Tp1>
01235     __weak_ptr&
01236     operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
01237     {
01238       _M_ptr = __r._M_ptr;
01239       _M_refcount = __r._M_refcount;
01240       return *this;
01241     }
01242 
01243       __shared_ptr<_Tp, _Lp>
01244       lock() const noexcept
01245       {
01246 #ifdef __GTHREADS
01247     // Optimization: avoid throw overhead.
01248     if (expired())
01249       return __shared_ptr<element_type, _Lp>();
01250 
01251     __try
01252       {
01253         return __shared_ptr<element_type, _Lp>(*this);
01254       }
01255     __catch(const bad_weak_ptr&)
01256       {
01257         // Q: How can we get here?
01258         // A: Another thread may have invalidated r after the
01259         //    use_count test above.
01260         return __shared_ptr<element_type, _Lp>();
01261       }
01262 
01263 #else
01264     // Optimization: avoid try/catch overhead when single threaded.
01265     return expired() ? __shared_ptr<element_type, _Lp>()
01266              : __shared_ptr<element_type, _Lp>(*this);
01267 
01268 #endif
01269       } // XXX MT
01270 
01271       long
01272       use_count() const noexcept
01273       { return _M_refcount._M_get_use_count(); }
01274 
01275       bool
01276       expired() const noexcept
01277       { return _M_refcount._M_get_use_count() == 0; }
01278 
01279       template<typename _Tp1>
01280     bool
01281     owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const
01282     { return _M_refcount._M_less(__rhs._M_refcount); }
01283 
01284       template<typename _Tp1>
01285     bool
01286     owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const
01287     { return _M_refcount._M_less(__rhs._M_refcount); }
01288 
01289       void
01290       reset() noexcept
01291       { __weak_ptr().swap(*this); }
01292 
01293       void
01294       swap(__weak_ptr& __s) noexcept
01295       {
01296     std::swap(_M_ptr, __s._M_ptr);
01297     _M_refcount._M_swap(__s._M_refcount);
01298       }
01299 
01300     private:
01301       // Used by __enable_shared_from_this.
01302       void
01303       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
01304       {
01305     _M_ptr = __ptr;
01306     _M_refcount = __refcount;
01307       }
01308 
01309       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
01310       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
01311       friend class __enable_shared_from_this<_Tp, _Lp>;
01312       friend class enable_shared_from_this<_Tp>;
01313 
01314       _Tp*       _M_ptr;         // Contained pointer.
01315       __weak_count<_Lp>  _M_refcount;    // Reference counter.
01316     };
01317 
01318   // 20.7.2.3.6 weak_ptr specialized algorithms.
01319   template<typename _Tp, _Lock_policy _Lp>
01320     inline void
01321     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
01322     { __a.swap(__b); }
01323 
01324   template<typename _Tp, typename _Tp1>
01325     struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
01326     {
01327       bool
01328       operator()(const _Tp& __lhs, const _Tp& __rhs) const
01329       { return __lhs.owner_before(__rhs); }
01330 
01331       bool
01332       operator()(const _Tp& __lhs, const _Tp1& __rhs) const
01333       { return __lhs.owner_before(__rhs); }
01334 
01335       bool
01336       operator()(const _Tp1& __lhs, const _Tp& __rhs) const
01337       { return __lhs.owner_before(__rhs); }
01338     };
01339 
01340   template<typename _Tp, _Lock_policy _Lp>
01341     struct owner_less<__shared_ptr<_Tp, _Lp>>
01342     : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
01343     { };
01344 
01345   template<typename _Tp, _Lock_policy _Lp>
01346     struct owner_less<__weak_ptr<_Tp, _Lp>>
01347     : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
01348     { };
01349 
01350 
01351   template<typename _Tp, _Lock_policy _Lp>
01352     class __enable_shared_from_this
01353     {
01354     protected:
01355       constexpr __enable_shared_from_this() noexcept { }
01356 
01357       __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
01358 
01359       __enable_shared_from_this&
01360       operator=(const __enable_shared_from_this&) noexcept
01361       { return *this; }
01362 
01363       ~__enable_shared_from_this() { }
01364 
01365     public:
01366       __shared_ptr<_Tp, _Lp>
01367       shared_from_this()
01368       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
01369 
01370       __shared_ptr<const _Tp, _Lp>
01371       shared_from_this() const
01372       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
01373 
01374     private:
01375       template<typename _Tp1>
01376     void
01377     _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
01378     { _M_weak_this._M_assign(__p, __n); }
01379 
01380       template<typename _Tp1>
01381     friend void
01382     __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
01383                      const __enable_shared_from_this* __pe,
01384                      const _Tp1* __px) noexcept
01385     {
01386       if (__pe != 0)
01387         __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
01388     }
01389 
01390       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
01391     };
01392 
01393 
01394   template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
01395     inline __shared_ptr<_Tp, _Lp>
01396     __allocate_shared(const _Alloc& __a, _Args&&... __args)
01397     {
01398       return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a,
01399                     std::forward<_Args>(__args)...);
01400     }
01401 
01402   template<typename _Tp, _Lock_policy _Lp, typename... _Args>
01403     inline __shared_ptr<_Tp, _Lp>
01404     __make_shared(_Args&&... __args)
01405     {
01406       typedef typename std::remove_const<_Tp>::type _Tp_nc;
01407       return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
01408                           std::forward<_Args>(__args)...);
01409     }
01410 
01411   /// std::hash specialization for __shared_ptr.
01412   template<typename _Tp, _Lock_policy _Lp>
01413     struct hash<__shared_ptr<_Tp, _Lp>>
01414     : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
01415     {
01416       size_t
01417       operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
01418       { return std::hash<_Tp*>()(__s.get()); }
01419     };
01420 
01421 _GLIBCXX_END_NAMESPACE_VERSION
01422 } // namespace
01423 
01424 #endif // _SHARED_PTR_BASE_H