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