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       virtual void
00347       _M_dispose() noexcept
00348       { _M_del._M_del(_M_ptr); }
00349 
00350       virtual void
00351       _M_destroy() noexcept
00352       {
00353     typedef typename allocator_traits<_Alloc>::template
00354       rebind_traits<_Sp_counted_deleter> _Alloc_traits;
00355     typename _Alloc_traits::allocator_type __a(_M_del);
00356     _Alloc_traits::destroy(__a, this);
00357     _Alloc_traits::deallocate(__a, this, 1);
00358       }
00359 
00360       virtual void*
00361       _M_get_deleter(const std::type_info& __ti)
00362       {
00363 #ifdef __GXX_RTTI
00364         return __ti == typeid(_Deleter) ? &_M_del._M_del : 0;
00365 #else
00366         return 0;
00367 #endif
00368       }
00369 
00370     protected:
00371       _Ptr             _M_ptr;  // copy constructor must not throw
00372       _My_Deleter      _M_del;  // copy constructor must not throw
00373     };
00374 
00375   // helpers for make_shared / allocate_shared
00376 
00377   struct _Sp_make_shared_tag { };
00378 
00379   template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
00380     class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
00381     {
00382       // Helper class that stores the pointer and also acts as an allocator.
00383       // Used to dispose of the owned pointer and the internal refcount
00384       // Requires that copies of _Alloc can free each other's memory.
00385       struct _Impl
00386       : public _Alloc           // copy constructor must not throw
00387       {
00388     _Impl(_Alloc __a) : _Alloc(__a), _M_ptr() { }
00389     _Tp* _M_ptr;
00390       };
00391 
00392     public:
00393       template<typename... _Args>
00394     _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
00395     : _M_impl(__a), _M_storage()
00396     {
00397       _M_impl._M_ptr = static_cast<_Tp*>(static_cast<void*>(&_M_storage));
00398       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00399       // 2070.  allocate_shared should use allocator_traits<A>::construct
00400       allocator_traits<_Alloc>::construct(__a, _M_impl._M_ptr,
00401           std::forward<_Args>(__args)...); // might throw
00402     }
00403 
00404       virtual void
00405       _M_dispose() noexcept
00406       { allocator_traits<_Alloc>::destroy(_M_impl, _M_impl._M_ptr); }
00407 
00408       // Override because the allocator needs to know the dynamic type
00409       virtual void
00410       _M_destroy() noexcept
00411       {
00412     typedef typename allocator_traits<_Alloc>::template
00413       rebind_traits<_Sp_counted_ptr_inplace> _Alloc_traits;
00414     typename _Alloc_traits::allocator_type __a(_M_impl);
00415     _Alloc_traits::destroy(__a, this);
00416     _Alloc_traits::deallocate(__a, this, 1);
00417       }
00418 
00419       // Sneaky trick so __shared_ptr can get the managed pointer
00420       virtual void*
00421       _M_get_deleter(const std::type_info& __ti) noexcept
00422       {
00423 #ifdef __GXX_RTTI
00424     return __ti == typeid(_Sp_make_shared_tag)
00425            ? static_cast<void*>(&_M_storage)
00426            : 0;
00427 #else
00428         return 0;
00429 #endif
00430       }
00431 
00432     private:
00433       _Impl _M_impl;
00434       typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type
00435     _M_storage;
00436     };
00437 
00438   template<_Lock_policy _Lp>
00439     class __shared_count
00440     {
00441     public:
00442       constexpr __shared_count() noexcept : _M_pi(0)
00443       { }
00444 
00445       template<typename _Ptr>
00446         explicit
00447     __shared_count(_Ptr __p) : _M_pi(0)
00448     {
00449       __try
00450         {
00451           _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
00452         }
00453       __catch(...)
00454         {
00455           delete __p;
00456           __throw_exception_again;
00457         }
00458     }
00459 
00460       template<typename _Ptr, typename _Deleter>
00461     __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
00462     {
00463       // The allocator's value_type doesn't matter, will rebind it anyway.
00464       typedef std::allocator<int> _Alloc;
00465       typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
00466       typedef typename allocator_traits<_Alloc>::template
00467         rebind_traits<_Sp_cd_type> _Alloc_traits;
00468       typename _Alloc_traits::allocator_type __a;
00469       _Sp_cd_type* __mem = 0;
00470       __try
00471         {
00472           __mem = _Alloc_traits::allocate(__a, 1);
00473           _Alloc_traits::construct(__a, __mem, __p, std::move(__d));
00474           _M_pi = __mem;
00475         }
00476       __catch(...)
00477         {
00478           __d(__p); // Call _Deleter on __p.
00479           if (__mem)
00480             _Alloc_traits::deallocate(__a, __mem, 1);
00481           __throw_exception_again;
00482         }
00483     }
00484 
00485       template<typename _Ptr, typename _Deleter, typename _Alloc>
00486     __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
00487     {
00488       typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
00489       typedef typename allocator_traits<_Alloc>::template
00490         rebind_traits<_Sp_cd_type> _Alloc_traits;
00491       typename _Alloc_traits::allocator_type __a2(__a);
00492       _Sp_cd_type* __mem = 0;
00493       __try
00494         {
00495           __mem = _Alloc_traits::allocate(__a2, 1);
00496           _Alloc_traits::construct(__a2, __mem,
00497           __p, std::move(__d), std::move(__a));
00498           _M_pi = __mem;
00499         }
00500       __catch(...)
00501         {
00502           __d(__p); // Call _Deleter on __p.
00503           if (__mem)
00504             _Alloc_traits::deallocate(__a2, __mem, 1);
00505           __throw_exception_again;
00506         }
00507     }
00508 
00509       template<typename _Tp, typename _Alloc, typename... _Args>
00510     __shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a,
00511                _Args&&... __args)
00512     : _M_pi(0)
00513     {
00514       typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
00515       typedef typename allocator_traits<_Alloc>::template
00516         rebind_traits<_Sp_cp_type> _Alloc_traits;
00517       typename _Alloc_traits::allocator_type __a2(__a);
00518       _Sp_cp_type* __mem = _Alloc_traits::allocate(__a2, 1);
00519       __try
00520         {
00521           _Alloc_traits::construct(__a2, __mem, std::move(__a),
00522             std::forward<_Args>(__args)...);
00523           _M_pi = __mem;
00524         }
00525       __catch(...)
00526         {
00527           _Alloc_traits::deallocate(__a2, __mem, 1);
00528           __throw_exception_again;
00529         }
00530     }
00531 
00532 #if _GLIBCXX_USE_DEPRECATED
00533       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
00534       template<typename _Tp>
00535         explicit
00536     __shared_count(std::auto_ptr<_Tp>&& __r)
00537     : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get()))
00538     { __r.release(); }
00539 #endif
00540 
00541       // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
00542       template<typename _Tp, typename _Del>
00543         explicit
00544     __shared_count(std::unique_ptr<_Tp, _Del>&& __r)
00545     : _M_pi(_S_create_from_up(std::move(__r)))
00546     { __r.release(); }
00547 
00548       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
00549       explicit __shared_count(const __weak_count<_Lp>& __r);
00550 
00551       ~__shared_count() noexcept
00552       {
00553     if (_M_pi != 0)
00554       _M_pi->_M_release();
00555       }
00556 
00557       __shared_count(const __shared_count& __r) noexcept
00558       : _M_pi(__r._M_pi)
00559       {
00560     if (_M_pi != 0)
00561       _M_pi->_M_add_ref_copy();
00562       }
00563 
00564       __shared_count&
00565       operator=(const __shared_count& __r) noexcept
00566       {
00567     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00568     if (__tmp != _M_pi)
00569       {
00570         if (__tmp != 0)
00571           __tmp->_M_add_ref_copy();
00572         if (_M_pi != 0)
00573           _M_pi->_M_release();
00574         _M_pi = __tmp;
00575       }
00576     return *this;
00577       }
00578 
00579       void
00580       _M_swap(__shared_count& __r) noexcept
00581       {
00582     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00583     __r._M_pi = _M_pi;
00584     _M_pi = __tmp;
00585       }
00586 
00587       long
00588       _M_get_use_count() const noexcept
00589       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
00590 
00591       bool
00592       _M_unique() const noexcept
00593       { return this->_M_get_use_count() == 1; }
00594 
00595       void*
00596       _M_get_deleter(const std::type_info& __ti) const noexcept
00597       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
00598 
00599       bool
00600       _M_less(const __shared_count& __rhs) const noexcept
00601       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00602 
00603       bool
00604       _M_less(const __weak_count<_Lp>& __rhs) const noexcept
00605       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00606 
00607       // Friend function injected into enclosing namespace and found by ADL
00608       friend inline bool
00609       operator==(const __shared_count& __a, const __shared_count& __b) noexcept
00610       { return __a._M_pi == __b._M_pi; }
00611 
00612     private:
00613       friend class __weak_count<_Lp>;
00614 
00615       template<typename _Tp, typename _Del>
00616     static _Sp_counted_base<_Lp>*
00617     _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
00618       typename std::enable_if<!std::is_reference<_Del>::value>::type* = 0)
00619     {
00620       return new _Sp_counted_deleter<_Tp*, _Del, std::allocator<_Tp>,
00621         _Lp>(__r.get(), __r.get_deleter());
00622     }
00623 
00624       template<typename _Tp, typename _Del>
00625     static _Sp_counted_base<_Lp>*
00626     _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
00627       typename std::enable_if<std::is_reference<_Del>::value>::type* = 0)
00628     {
00629       typedef typename std::remove_reference<_Del>::type _Del1;
00630       typedef std::reference_wrapper<_Del1> _Del2;
00631       return new _Sp_counted_deleter<_Tp*, _Del2, std::allocator<_Tp>,
00632         _Lp>(__r.get(), std::ref(__r.get_deleter()));
00633     }
00634 
00635       _Sp_counted_base<_Lp>*  _M_pi;
00636     };
00637 
00638 
00639   template<_Lock_policy _Lp>
00640     class __weak_count
00641     {
00642     public:
00643       constexpr __weak_count() noexcept : _M_pi(0)
00644       { }
00645 
00646       __weak_count(const __shared_count<_Lp>& __r) noexcept
00647       : _M_pi(__r._M_pi)
00648       {
00649     if (_M_pi != 0)
00650       _M_pi->_M_weak_add_ref();
00651       }
00652 
00653       __weak_count(const __weak_count<_Lp>& __r) noexcept
00654       : _M_pi(__r._M_pi)
00655       {
00656     if (_M_pi != 0)
00657       _M_pi->_M_weak_add_ref();
00658       }
00659 
00660       ~__weak_count() noexcept
00661       {
00662     if (_M_pi != 0)
00663       _M_pi->_M_weak_release();
00664       }
00665 
00666       __weak_count<_Lp>&
00667       operator=(const __shared_count<_Lp>& __r) noexcept
00668       {
00669     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00670     if (__tmp != 0)
00671       __tmp->_M_weak_add_ref();
00672     if (_M_pi != 0)
00673       _M_pi->_M_weak_release();
00674     _M_pi = __tmp;
00675     return *this;
00676       }
00677 
00678       __weak_count<_Lp>&
00679       operator=(const __weak_count<_Lp>& __r) noexcept
00680       {
00681     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00682     if (__tmp != 0)
00683       __tmp->_M_weak_add_ref();
00684     if (_M_pi != 0)
00685       _M_pi->_M_weak_release();
00686     _M_pi = __tmp;
00687     return *this;
00688       }
00689 
00690       void
00691       _M_swap(__weak_count<_Lp>& __r) noexcept
00692       {
00693     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00694     __r._M_pi = _M_pi;
00695     _M_pi = __tmp;
00696       }
00697 
00698       long
00699       _M_get_use_count() const noexcept
00700       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
00701 
00702       bool
00703       _M_less(const __weak_count& __rhs) const noexcept
00704       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00705 
00706       bool
00707       _M_less(const __shared_count<_Lp>& __rhs) const noexcept
00708       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00709 
00710       // Friend function injected into enclosing namespace and found by ADL
00711       friend inline bool
00712       operator==(const __weak_count& __a, const __weak_count& __b) noexcept
00713       { return __a._M_pi == __b._M_pi; }
00714 
00715     private:
00716       friend class __shared_count<_Lp>;
00717 
00718       _Sp_counted_base<_Lp>*  _M_pi;
00719     };
00720 
00721   // Now that __weak_count is defined we can define this constructor:
00722   template<_Lock_policy _Lp>
00723     inline __shared_count<_Lp>:: __shared_count(const __weak_count<_Lp>& __r)
00724     : _M_pi(__r._M_pi)
00725     {
00726       if (_M_pi != 0)
00727     _M_pi->_M_add_ref_lock();
00728       else
00729     __throw_bad_weak_ptr();
00730     }
00731 
00732 
00733   // Support for enable_shared_from_this.
00734 
00735   // Friend of __enable_shared_from_this.
00736   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
00737     void
00738     __enable_shared_from_this_helper(const __shared_count<_Lp>&,
00739                      const __enable_shared_from_this<_Tp1,
00740                      _Lp>*, const _Tp2*) noexcept;
00741 
00742   // Friend of enable_shared_from_this.
00743   template<typename _Tp1, typename _Tp2>
00744     void
00745     __enable_shared_from_this_helper(const __shared_count<>&,
00746                      const enable_shared_from_this<_Tp1>*,
00747                      const _Tp2*) noexcept;
00748 
00749   template<_Lock_policy _Lp>
00750     inline void
00751     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) noexcept
00752     { }
00753 
00754 
00755   template<typename _Tp, _Lock_policy _Lp>
00756     class __shared_ptr
00757     {
00758     public:
00759       typedef _Tp   element_type;
00760 
00761       constexpr __shared_ptr() noexcept
00762       : _M_ptr(0), _M_refcount()
00763       { }
00764 
00765       template<typename _Tp1>
00766     explicit __shared_ptr(_Tp1* __p)
00767         : _M_ptr(__p), _M_refcount(__p)
00768     {
00769       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00770       static_assert( sizeof(_Tp1) > 0, "incomplete type" );
00771       __enable_shared_from_this_helper(_M_refcount, __p, __p);
00772     }
00773 
00774       template<typename _Tp1, typename _Deleter>
00775     __shared_ptr(_Tp1* __p, _Deleter __d)
00776     : _M_ptr(__p), _M_refcount(__p, __d)
00777     {
00778       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00779       // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
00780       __enable_shared_from_this_helper(_M_refcount, __p, __p);
00781     }
00782 
00783       template<typename _Tp1, typename _Deleter, typename _Alloc>
00784     __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
00785     : _M_ptr(__p), _M_refcount(__p, __d, std::move(__a))
00786     {
00787       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00788       // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
00789       __enable_shared_from_this_helper(_M_refcount, __p, __p);
00790     }
00791 
00792       template<typename _Deleter>
00793     __shared_ptr(nullptr_t __p, _Deleter __d)
00794     : _M_ptr(0), _M_refcount(__p, __d)
00795     { }
00796 
00797       template<typename _Deleter, typename _Alloc>
00798         __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
00799     : _M_ptr(0), _M_refcount(__p, __d, std::move(__a))
00800     { }
00801 
00802       template<typename _Tp1>
00803     __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept
00804     : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
00805     { }
00806 
00807       __shared_ptr(const __shared_ptr&) noexcept = default;
00808       __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
00809       ~__shared_ptr() = default;
00810 
00811       template<typename _Tp1, typename = typename
00812            std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
00813     __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
00814     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
00815     { }
00816 
00817       __shared_ptr(__shared_ptr&& __r) noexcept
00818       : _M_ptr(__r._M_ptr), _M_refcount()
00819       {
00820     _M_refcount._M_swap(__r._M_refcount);
00821     __r._M_ptr = 0;
00822       }
00823 
00824       template<typename _Tp1, typename = typename
00825            std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
00826     __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
00827     : _M_ptr(__r._M_ptr), _M_refcount()
00828     {
00829       _M_refcount._M_swap(__r._M_refcount);
00830       __r._M_ptr = 0;
00831     }
00832 
00833       template<typename _Tp1>
00834     explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
00835     : _M_refcount(__r._M_refcount) // may throw
00836     {
00837       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00838 
00839       // It is now safe to copy __r._M_ptr, as
00840       // _M_refcount(__r._M_refcount) did not throw.
00841       _M_ptr = __r._M_ptr;
00842     }
00843 
00844       // If an exception is thrown this constructor has no effect.
00845       template<typename _Tp1, typename _Del>
00846     __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
00847     : _M_ptr(__r.get()), _M_refcount()
00848     {
00849       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00850       _Tp1* __tmp = __r.get();
00851       _M_refcount = __shared_count<_Lp>(std::move(__r));
00852       __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
00853     }
00854 
00855 #if _GLIBCXX_USE_DEPRECATED
00856       // Postcondition: use_count() == 1 and __r.get() == 0
00857       template<typename _Tp1>
00858     __shared_ptr(std::auto_ptr<_Tp1>&& __r)
00859     : _M_ptr(__r.get()), _M_refcount()
00860     {
00861       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00862       static_assert( sizeof(_Tp1) > 0, "incomplete type" );
00863       _Tp1* __tmp = __r.get();
00864       _M_refcount = __shared_count<_Lp>(std::move(__r));
00865       __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
00866     }
00867 #endif
00868 
00869       /* TODO: use delegating constructor */
00870       constexpr __shared_ptr(nullptr_t) noexcept
00871       : _M_ptr(0), _M_refcount()
00872       { }
00873 
00874       template<typename _Tp1>
00875     __shared_ptr&
00876     operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
00877     {
00878       _M_ptr = __r._M_ptr;
00879       _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
00880       return *this;
00881     }
00882 
00883 #if _GLIBCXX_USE_DEPRECATED
00884       template<typename _Tp1>
00885     __shared_ptr&
00886     operator=(std::auto_ptr<_Tp1>&& __r)
00887     {
00888       __shared_ptr(std::move(__r)).swap(*this);
00889       return *this;
00890     }
00891 #endif
00892 
00893       __shared_ptr&
00894       operator=(__shared_ptr&& __r) noexcept
00895       {
00896     __shared_ptr(std::move(__r)).swap(*this);
00897     return *this;
00898       }
00899 
00900       template<class _Tp1>
00901     __shared_ptr&
00902     operator=(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
00903     {
00904       __shared_ptr(std::move(__r)).swap(*this);
00905       return *this;
00906     }
00907 
00908       template<typename _Tp1, typename _Del>
00909     __shared_ptr&
00910     operator=(std::unique_ptr<_Tp1, _Del>&& __r)
00911     {
00912       __shared_ptr(std::move(__r)).swap(*this);
00913       return *this;
00914     }
00915 
00916       void
00917       reset() noexcept
00918       { __shared_ptr().swap(*this); }
00919 
00920       template<typename _Tp1>
00921     void
00922     reset(_Tp1* __p) // _Tp1 must be complete.
00923     {
00924       // Catch self-reset errors.
00925       _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
00926       __shared_ptr(__p).swap(*this);
00927     }
00928 
00929       template<typename _Tp1, typename _Deleter>
00930     void
00931     reset(_Tp1* __p, _Deleter __d)
00932     { __shared_ptr(__p, __d).swap(*this); }
00933 
00934       template<typename _Tp1, typename _Deleter, typename _Alloc>
00935     void
00936         reset(_Tp1* __p, _Deleter __d, _Alloc __a)
00937         { __shared_ptr(__p, __d, std::move(__a)).swap(*this); }
00938 
00939       // Allow class instantiation when _Tp is [cv-qual] void.
00940       typename std::add_lvalue_reference<_Tp>::type
00941       operator*() const noexcept
00942       {
00943     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00944     return *_M_ptr;
00945       }
00946 
00947       _Tp*
00948       operator->() const noexcept
00949       {
00950     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00951     return _M_ptr;
00952       }
00953 
00954       _Tp*
00955       get() const noexcept
00956       { return _M_ptr; }
00957 
00958       explicit operator bool() const // never throws
00959       { return _M_ptr == 0 ? false : true; }
00960 
00961       bool
00962       unique() const noexcept
00963       { return _M_refcount._M_unique(); }
00964 
00965       long
00966       use_count() const noexcept
00967       { return _M_refcount._M_get_use_count(); }
00968 
00969       void
00970       swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
00971       {
00972     std::swap(_M_ptr, __other._M_ptr);
00973     _M_refcount._M_swap(__other._M_refcount);
00974       }
00975 
00976       template<typename _Tp1>
00977     bool
00978     owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const
00979     { return _M_refcount._M_less(__rhs._M_refcount); }
00980 
00981       template<typename _Tp1>
00982     bool
00983     owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const
00984     { return _M_refcount._M_less(__rhs._M_refcount); }
00985 
00986 #ifdef __GXX_RTTI
00987     protected:
00988       // This constructor is non-standard, it is used by allocate_shared.
00989       template<typename _Alloc, typename... _Args>
00990     __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
00991              _Args&&... __args)
00992     : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
00993                 std::forward<_Args>(__args)...)
00994     {
00995       // _M_ptr needs to point to the newly constructed object.
00996       // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
00997       void* __p = _M_refcount._M_get_deleter(typeid(__tag));
00998       _M_ptr = static_cast<_Tp*>(__p);
00999       __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
01000     }
01001 #else
01002       template<typename _Alloc>
01003         struct _Deleter
01004         {
01005           void operator()(_Tp* __ptr)
01006           {
01007         typedef allocator_traits<_Alloc> _Alloc_traits;
01008         _Alloc_traits::destroy(_M_alloc, __ptr);
01009         _Alloc_traits::deallocate(_M_alloc, __ptr, 1);
01010           }
01011           _Alloc _M_alloc;
01012         };
01013 
01014       template<typename _Alloc, typename... _Args>
01015     __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
01016              _Args&&... __args)
01017     : _M_ptr(), _M_refcount()
01018         {
01019       typedef typename _Alloc::template rebind<_Tp>::other _Alloc2;
01020           _Deleter<_Alloc2> __del = { _Alloc2(__a) };
01021       typedef allocator_traits<_Alloc2> __traits;
01022           _M_ptr = __traits::allocate(__del._M_alloc, 1);
01023       __try
01024         {
01025           // _GLIBCXX_RESOLVE_LIB_DEFECTS
01026           // 2070. allocate_shared should use allocator_traits<A>::construct
01027           __traits::construct(__del._M_alloc, _M_ptr,
01028                           std::forward<_Args>(__args)...);
01029         }
01030       __catch(...)
01031         {
01032           __traits::deallocate(__del._M_alloc, _M_ptr, 1);
01033           __throw_exception_again;
01034         }
01035           __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);
01036           _M_refcount._M_swap(__count);
01037       __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
01038         }
01039 #endif
01040 
01041       template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
01042            typename... _Args>
01043     friend __shared_ptr<_Tp1, _Lp1>
01044     __allocate_shared(const _Alloc& __a, _Args&&... __args);
01045 
01046     private:
01047       void*
01048       _M_get_deleter(const std::type_info& __ti) const noexcept
01049       { return _M_refcount._M_get_deleter(__ti); }
01050 
01051       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
01052       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
01053 
01054       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
01055     friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
01056 
01057       _Tp*         _M_ptr;         // Contained pointer.
01058       __shared_count<_Lp>  _M_refcount;    // Reference counter.
01059     };
01060 
01061 
01062   // 20.8.13.2.7 shared_ptr comparisons
01063   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01064     inline bool
01065     operator==(const __shared_ptr<_Tp1, _Lp>& __a,
01066            const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01067     { return __a.get() == __b.get(); }
01068 
01069   template<typename _Tp, _Lock_policy _Lp>
01070     inline bool
01071     operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01072     { return !__a; }
01073 
01074   template<typename _Tp, _Lock_policy _Lp>
01075     inline bool
01076     operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01077     { return !__a; }
01078 
01079   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01080     inline bool
01081     operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
01082            const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01083     { return __a.get() != __b.get(); }
01084 
01085   template<typename _Tp, _Lock_policy _Lp>
01086     inline bool
01087     operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01088     { return (bool)__a; }
01089 
01090   template<typename _Tp, _Lock_policy _Lp>
01091     inline bool
01092     operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01093     { return (bool)__a; }
01094 
01095   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01096     inline bool
01097     operator<(const __shared_ptr<_Tp1, _Lp>& __a,
01098           const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01099     {
01100       typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
01101       return std::less<_CT>()(__a.get(), __b.get());
01102     }
01103 
01104   template<typename _Tp, _Lock_policy _Lp>
01105     inline bool
01106     operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01107     { return std::less<_Tp*>()(__a.get(), nullptr); }
01108 
01109   template<typename _Tp, _Lock_policy _Lp>
01110     inline bool
01111     operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01112     { return std::less<_Tp*>()(nullptr, __a.get()); }
01113 
01114   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01115     inline bool
01116     operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
01117            const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01118     { return !(__b < __a); }
01119 
01120   template<typename _Tp, _Lock_policy _Lp>
01121     inline bool
01122     operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01123     { return !(nullptr < __a); }
01124 
01125   template<typename _Tp, _Lock_policy _Lp>
01126     inline bool
01127     operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01128     { return !(__a < nullptr); }
01129 
01130   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01131     inline bool
01132     operator>(const __shared_ptr<_Tp1, _Lp>& __a,
01133           const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01134     { return (__b < __a); }
01135 
01136   template<typename _Tp, _Lock_policy _Lp>
01137     inline bool
01138     operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01139     { return std::less<_Tp*>()(nullptr, __a.get()); }
01140 
01141   template<typename _Tp, _Lock_policy _Lp>
01142     inline bool
01143     operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01144     { return std::less<_Tp*>()(__a.get(), nullptr); }
01145 
01146   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
01147     inline bool
01148     operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
01149            const __shared_ptr<_Tp2, _Lp>& __b) noexcept
01150     { return !(__a < __b); }
01151 
01152   template<typename _Tp, _Lock_policy _Lp>
01153     inline bool
01154     operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
01155     { return !(__a < nullptr); }
01156 
01157   template<typename _Tp, _Lock_policy _Lp>
01158     inline bool
01159     operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
01160     { return !(nullptr < __a); }
01161 
01162   template<typename _Sp>
01163     struct _Sp_less : public binary_function<_Sp, _Sp, bool>
01164     {
01165       bool
01166       operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept
01167       {
01168     typedef typename _Sp::element_type element_type;
01169     return std::less<element_type*>()(__lhs.get(), __rhs.get());
01170       }
01171     };
01172 
01173   template<typename _Tp, _Lock_policy _Lp>
01174     struct less<__shared_ptr<_Tp, _Lp>>
01175     : public _Sp_less<__shared_ptr<_Tp, _Lp>>
01176     { };
01177 
01178   // 2.2.3.8 shared_ptr specialized algorithms.
01179   template<typename _Tp, _Lock_policy _Lp>
01180     inline void
01181     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
01182     { __a.swap(__b); }
01183 
01184   // 2.2.3.9 shared_ptr casts
01185 
01186   // The seemingly equivalent code:
01187   // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
01188   // will eventually result in undefined behaviour, attempting to
01189   // delete the same object twice.
01190   /// static_pointer_cast
01191   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
01192     inline __shared_ptr<_Tp, _Lp>
01193     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
01194     { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
01195 
01196   // The seemingly equivalent code:
01197   // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
01198   // will eventually result in undefined behaviour, attempting to
01199   // delete the same object twice.
01200   /// const_pointer_cast
01201   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
01202     inline __shared_ptr<_Tp, _Lp>
01203     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
01204     { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
01205 
01206   // The seemingly equivalent code:
01207   // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
01208   // will eventually result in undefined behaviour, attempting to
01209   // delete the same object twice.
01210   /// dynamic_pointer_cast
01211   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
01212     inline __shared_ptr<_Tp, _Lp>
01213     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
01214     {
01215       if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
01216     return __shared_ptr<_Tp, _Lp>(__r, __p);
01217       return __shared_ptr<_Tp, _Lp>();
01218     }
01219 
01220 
01221   template<typename _Tp, _Lock_policy _Lp>
01222     class __weak_ptr
01223     {
01224     public:
01225       typedef _Tp element_type;
01226 
01227       constexpr __weak_ptr() noexcept
01228       : _M_ptr(0), _M_refcount()
01229       { }
01230 
01231       __weak_ptr(const __weak_ptr&) noexcept = default;
01232       __weak_ptr& operator=(const __weak_ptr&) noexcept = default;
01233       ~__weak_ptr() = default;
01234 
01235       // The "obvious" converting constructor implementation:
01236       //
01237       //  template<typename _Tp1>
01238       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
01239       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
01240       //    { }
01241       //
01242       // has a serious problem.
01243       //
01244       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
01245       //  conversion may require access to *__r._M_ptr (virtual inheritance).
01246       //
01247       // It is not possible to avoid spurious access violations since
01248       // in multithreaded programs __r._M_ptr may be invalidated at any point.
01249       template<typename _Tp1, typename = typename
01250            std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
01251     __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
01252     : _M_refcount(__r._M_refcount)
01253         { _M_ptr = __r.lock().get(); }
01254 
01255       template<typename _Tp1, typename = typename
01256            std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
01257     __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
01258     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
01259     { }
01260 
01261       template<typename _Tp1>
01262     __weak_ptr&
01263     operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
01264     {
01265       _M_ptr = __r.lock().get();
01266       _M_refcount = __r._M_refcount;
01267       return *this;
01268     }
01269 
01270       template<typename _Tp1>
01271     __weak_ptr&
01272     operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
01273     {
01274       _M_ptr = __r._M_ptr;
01275       _M_refcount = __r._M_refcount;
01276       return *this;
01277     }
01278 
01279       __shared_ptr<_Tp, _Lp>
01280       lock() const noexcept
01281       {
01282 #ifdef __GTHREADS
01283     // Optimization: avoid throw overhead.
01284     if (expired())
01285       return __shared_ptr<element_type, _Lp>();
01286 
01287     __try
01288       {
01289         return __shared_ptr<element_type, _Lp>(*this);
01290       }
01291     __catch(const bad_weak_ptr&)
01292       {
01293         // Q: How can we get here?
01294         // A: Another thread may have invalidated r after the
01295         //    use_count test above.
01296         return __shared_ptr<element_type, _Lp>();
01297       }
01298 
01299 #else
01300     // Optimization: avoid try/catch overhead when single threaded.
01301     return expired() ? __shared_ptr<element_type, _Lp>()
01302              : __shared_ptr<element_type, _Lp>(*this);
01303 
01304 #endif
01305       } // XXX MT
01306 
01307       long
01308       use_count() const noexcept
01309       { return _M_refcount._M_get_use_count(); }
01310 
01311       bool
01312       expired() const noexcept
01313       { return _M_refcount._M_get_use_count() == 0; }
01314 
01315       template<typename _Tp1>
01316     bool
01317     owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const
01318     { return _M_refcount._M_less(__rhs._M_refcount); }
01319 
01320       template<typename _Tp1>
01321     bool
01322     owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const
01323     { return _M_refcount._M_less(__rhs._M_refcount); }
01324 
01325       void
01326       reset() noexcept
01327       { __weak_ptr().swap(*this); }
01328 
01329       void
01330       swap(__weak_ptr& __s) noexcept
01331       {
01332     std::swap(_M_ptr, __s._M_ptr);
01333     _M_refcount._M_swap(__s._M_refcount);
01334       }
01335 
01336     private:
01337       // Used by __enable_shared_from_this.
01338       void
01339       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
01340       {
01341     _M_ptr = __ptr;
01342     _M_refcount = __refcount;
01343       }
01344 
01345       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
01346       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
01347       friend class __enable_shared_from_this<_Tp, _Lp>;
01348       friend class enable_shared_from_this<_Tp>;
01349 
01350       _Tp*       _M_ptr;         // Contained pointer.
01351       __weak_count<_Lp>  _M_refcount;    // Reference counter.
01352     };
01353 
01354   // 20.8.13.3.7 weak_ptr specialized algorithms.
01355   template<typename _Tp, _Lock_policy _Lp>
01356     inline void
01357     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
01358     { __a.swap(__b); }
01359 
01360   template<typename _Tp, typename _Tp1>
01361     struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
01362     {
01363       bool
01364       operator()(const _Tp& __lhs, const _Tp& __rhs) const
01365       { return __lhs.owner_before(__rhs); }
01366 
01367       bool
01368       operator()(const _Tp& __lhs, const _Tp1& __rhs) const
01369       { return __lhs.owner_before(__rhs); }
01370 
01371       bool
01372       operator()(const _Tp1& __lhs, const _Tp& __rhs) const
01373       { return __lhs.owner_before(__rhs); }
01374     };
01375 
01376   template<typename _Tp, _Lock_policy _Lp>
01377     struct owner_less<__shared_ptr<_Tp, _Lp>>
01378     : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
01379     { };
01380 
01381   template<typename _Tp, _Lock_policy _Lp>
01382     struct owner_less<__weak_ptr<_Tp, _Lp>>
01383     : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
01384     { };
01385 
01386 
01387   template<typename _Tp, _Lock_policy _Lp>
01388     class __enable_shared_from_this
01389     {
01390     protected:
01391       constexpr __enable_shared_from_this() noexcept { }
01392 
01393       __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
01394 
01395       __enable_shared_from_this&
01396       operator=(const __enable_shared_from_this&) noexcept
01397       { return *this; }
01398 
01399       ~__enable_shared_from_this() { }
01400 
01401     public:
01402       __shared_ptr<_Tp, _Lp>
01403       shared_from_this()
01404       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
01405 
01406       __shared_ptr<const _Tp, _Lp>
01407       shared_from_this() const
01408       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
01409 
01410     private:
01411       template<typename _Tp1>
01412     void
01413     _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
01414     { _M_weak_this._M_assign(__p, __n); }
01415 
01416       template<typename _Tp1>
01417     friend void
01418     __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
01419                      const __enable_shared_from_this* __pe,
01420                      const _Tp1* __px) noexcept
01421     {
01422       if (__pe != 0)
01423         __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
01424     }
01425 
01426       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
01427     };
01428 
01429 
01430   template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
01431     inline __shared_ptr<_Tp, _Lp>
01432     __allocate_shared(const _Alloc& __a, _Args&&... __args)
01433     {
01434       return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a,
01435                     std::forward<_Args>(__args)...);
01436     }
01437 
01438   template<typename _Tp, _Lock_policy _Lp, typename... _Args>
01439     inline __shared_ptr<_Tp, _Lp>
01440     __make_shared(_Args&&... __args)
01441     {
01442       typedef typename std::remove_const<_Tp>::type _Tp_nc;
01443       return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
01444                           std::forward<_Args>(__args)...);
01445     }
01446 
01447   /// std::hash specialization for __shared_ptr.
01448   template<typename _Tp, _Lock_policy _Lp>
01449     struct hash<__shared_ptr<_Tp, _Lp>>
01450     : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
01451     {
01452       size_t
01453       operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
01454       { return std::hash<_Tp*>()(__s.get()); }
01455     };
01456 
01457 _GLIBCXX_END_NAMESPACE_VERSION
01458 } // namespace
01459 
01460 #endif // _SHARED_PTR_BASE_H