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