Home | History | Annotate | Download | only in bits
      1 // shared_ptr and weak_ptr implementation details -*- C++ -*-
      2 
      3 // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 // GCC Note: Based on files from version 1.32.0 of the Boost library.
     26 
     27 //  shared_count.hpp
     28 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
     29 
     30 //  shared_ptr.hpp
     31 //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
     32 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
     33 
     34 //  weak_ptr.hpp
     35 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
     36 
     37 //  enable_shared_from_this.hpp
     38 //  Copyright (C) 2002 Peter Dimov
     39 
     40 // Distributed under the Boost Software License, Version 1.0. (See
     41 // accompanying file LICENSE_1_0.txt or copy at
     42 // http://www.boost.org/LICENSE_1_0.txt)
     43 
     44 /** @file bits/shared_ptr_base.h
     45  *  This is an internal header file, included by other library headers.
     46  *  Do not attempt to use it directly. @headername{memory}
     47  */
     48 
     49 #ifndef _SHARED_PTR_BASE_H
     50 #define _SHARED_PTR_BASE_H 1
     51 
     52 namespace std _GLIBCXX_VISIBILITY(default)
     53 {
     54 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     55 
     56  /**
     57    *  @brief  Exception possibly thrown by @c shared_ptr.
     58    *  @ingroup exceptions
     59    */
     60   class bad_weak_ptr : public std::exception
     61   {
     62   public:
     63     virtual char const*
     64     what() const throw();
     65 
     66     virtual ~bad_weak_ptr() throw();
     67   };
     68 
     69   // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
     70   inline void
     71   __throw_bad_weak_ptr()
     72   {
     73 #if __EXCEPTIONS
     74     throw bad_weak_ptr();
     75 #else
     76     __builtin_abort();
     77 #endif
     78   }
     79 
     80   using __gnu_cxx::_Lock_policy;
     81   using __gnu_cxx::__default_lock_policy;
     82   using __gnu_cxx::_S_single;
     83   using __gnu_cxx::_S_mutex;
     84   using __gnu_cxx::_S_atomic;
     85 
     86   // Empty helper class except when the template argument is _S_mutex.
     87   template<_Lock_policy _Lp>
     88     class _Mutex_base
     89     {
     90     protected:
     91       // The atomic policy uses fully-fenced builtins, single doesn't care.
     92       enum { _S_need_barriers = 0 };
     93     };
     94 
     95   template<>
     96     class _Mutex_base<_S_mutex>
     97     : public __gnu_cxx::__mutex
     98     {
     99     protected:
    100       // This policy is used when atomic builtins are not available.
    101       // The replacement atomic operations might not have the necessary
    102       // memory barriers.
    103       enum { _S_need_barriers = 1 };
    104     };
    105 
    106   template<_Lock_policy _Lp = __default_lock_policy>
    107     class _Sp_counted_base
    108     : public _Mutex_base<_Lp>
    109     {
    110     public:
    111       _Sp_counted_base()
    112       : _M_use_count(1), _M_weak_count(1) { }
    113 
    114       virtual
    115       ~_Sp_counted_base() // nothrow
    116       { }
    117 
    118       // Called when _M_use_count drops to zero, to release the resources
    119       // managed by *this.
    120       virtual void
    121       _M_dispose() = 0; // nothrow
    122 
    123       // Called when _M_weak_count drops to zero.
    124       virtual void
    125       _M_destroy() // nothrow
    126       { delete this; }
    127 
    128       virtual void*
    129       _M_get_deleter(const std::type_info&) = 0;
    130 
    131       void
    132       _M_add_ref_copy()
    133       { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
    134 
    135       void
    136       _M_add_ref_lock();
    137 
    138       void
    139       _M_release() // nothrow
    140       {
    141         // Be race-detector-friendly.  For more info see bits/c++config.
    142         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
    143 	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
    144 	  {
    145             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
    146 	    _M_dispose();
    147 	    // There must be a memory barrier between dispose() and destroy()
    148 	    // to ensure that the effects of dispose() are observed in the
    149 	    // thread that runs destroy().
    150 	    // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
    151 	    if (_Mutex_base<_Lp>::_S_need_barriers)
    152 	      {
    153 	        _GLIBCXX_READ_MEM_BARRIER;
    154 	        _GLIBCXX_WRITE_MEM_BARRIER;
    155 	      }
    156 
    157             // Be race-detector-friendly.  For more info see bits/c++config.
    158             _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
    159 	    if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
    160 						       -1) == 1)
    161               {
    162                 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
    163 	        _M_destroy();
    164               }
    165 	  }
    166       }
    167 
    168       void
    169       _M_weak_add_ref() // nothrow
    170       { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
    171 
    172       void
    173       _M_weak_release() // nothrow
    174       {
    175         // Be race-detector-friendly. For more info see bits/c++config.
    176         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
    177 	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
    178 	  {
    179             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
    180 	    if (_Mutex_base<_Lp>::_S_need_barriers)
    181 	      {
    182 	        // See _M_release(),
    183 	        // destroy() must observe results of dispose()
    184 	        _GLIBCXX_READ_MEM_BARRIER;
    185 	        _GLIBCXX_WRITE_MEM_BARRIER;
    186 	      }
    187 	    _M_destroy();
    188 	  }
    189       }
    190 
    191       long
    192       _M_get_use_count() const // nothrow
    193       {
    194         // No memory barrier is used here so there is no synchronization
    195         // with other threads.
    196         return const_cast<const volatile _Atomic_word&>(_M_use_count);
    197       }
    198 
    199     private:
    200       _Sp_counted_base(_Sp_counted_base const&);
    201       _Sp_counted_base& operator=(_Sp_counted_base const&);
    202 
    203       _Atomic_word  _M_use_count;     // #shared
    204       _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
    205     };
    206 
    207   template<>
    208     inline void
    209     _Sp_counted_base<_S_single>::
    210     _M_add_ref_lock()
    211     {
    212       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
    213 	{
    214 	  _M_use_count = 0;
    215 	  __throw_bad_weak_ptr();
    216 	}
    217     }
    218 
    219   template<>
    220     inline void
    221     _Sp_counted_base<_S_mutex>::
    222     _M_add_ref_lock()
    223     {
    224       __gnu_cxx::__scoped_lock sentry(*this);
    225       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
    226 	{
    227 	  _M_use_count = 0;
    228 	  __throw_bad_weak_ptr();
    229 	}
    230     }
    231 
    232   template<>
    233     inline void
    234     _Sp_counted_base<_S_atomic>::
    235     _M_add_ref_lock()
    236     {
    237       // Perform lock-free add-if-not-zero operation.
    238       _Atomic_word __count;
    239       do
    240 	{
    241 	  __count = _M_use_count;
    242 	  if (__count == 0)
    243 	    __throw_bad_weak_ptr();
    244 
    245 	  // Replace the current counter value with the old value + 1, as
    246 	  // long as it's not changed meanwhile.
    247 	}
    248       while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
    249 					   __count + 1));
    250     }
    251 
    252 
    253   // Forward declarations.
    254   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    255     class __shared_ptr;
    256 
    257   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    258     class __weak_ptr;
    259 
    260   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    261     class __enable_shared_from_this;
    262 
    263   template<typename _Tp>
    264     class shared_ptr;
    265 
    266   template<typename _Tp>
    267     class weak_ptr;
    268 
    269   template<typename _Tp>
    270     struct owner_less;
    271 
    272   template<typename _Tp>
    273     class enable_shared_from_this;
    274 
    275   template<_Lock_policy _Lp = __default_lock_policy>
    276     class __weak_count;
    277 
    278   template<_Lock_policy _Lp = __default_lock_policy>
    279     class __shared_count;
    280 
    281 
    282   // Counted ptr with no deleter or allocator support
    283   template<typename _Ptr, _Lock_policy _Lp>
    284     class _Sp_counted_ptr : public _Sp_counted_base<_Lp>
    285     {
    286     public:
    287       explicit
    288       _Sp_counted_ptr(_Ptr __p)
    289       : _M_ptr(__p) { }
    290 
    291       virtual void
    292       _M_dispose() // nothrow
    293       { delete _M_ptr; }
    294 
    295       virtual void
    296       _M_destroy() // nothrow
    297       { delete this; }
    298 
    299       virtual void*
    300       _M_get_deleter(const std::type_info&)
    301       { return 0; }
    302 
    303       _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
    304       _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
    305 
    306     protected:
    307       _Ptr             _M_ptr;  // copy constructor must not throw
    308     };
    309 
    310   template<>
    311     inline void
    312     _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() { }
    313 
    314   template<>
    315     inline void
    316     _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() { }
    317 
    318   template<>
    319     inline void
    320     _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() { }
    321 
    322   // Support for custom deleter and/or allocator
    323   template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
    324     class _Sp_counted_deleter : public _Sp_counted_base<_Lp>
    325     {
    326       typedef typename _Alloc::template
    327 	  rebind<_Sp_counted_deleter>::other _My_alloc_type;
    328 
    329       // Helper class that stores the Deleter and also acts as an allocator.
    330       // Used to dispose of the owned pointer and the internal refcount
    331       // Requires that copies of _Alloc can free each other's memory.
    332       struct _My_Deleter
    333       : public _My_alloc_type    // copy constructor must not throw
    334       {
    335 	_Deleter _M_del;         // copy constructor must not throw
    336 	_My_Deleter(_Deleter __d, const _Alloc& __a)
    337 	: _My_alloc_type(__a), _M_del(__d) { }
    338       };
    339 
    340     public:
    341       // __d(__p) must not throw.
    342       _Sp_counted_deleter(_Ptr __p, _Deleter __d)
    343       : _M_ptr(__p), _M_del(__d, _Alloc()) { }
    344 
    345       // __d(__p) must not throw.
    346       _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a)
    347       : _M_ptr(__p), _M_del(__d, __a) { }
    348 
    349       virtual void
    350       _M_dispose() // nothrow
    351       { _M_del._M_del(_M_ptr); }
    352 
    353       virtual void
    354       _M_destroy() // nothrow
    355       {
    356 	_My_alloc_type __a(_M_del);
    357 	this->~_Sp_counted_deleter();
    358 	__a.deallocate(this, 1);
    359       }
    360 
    361       virtual void*
    362       _M_get_deleter(const std::type_info& __ti)
    363       {
    364 #ifdef __GXX_RTTI
    365         return __ti == typeid(_Deleter) ? &_M_del._M_del : 0;
    366 #else
    367         return 0;
    368 #endif
    369       }
    370 
    371     protected:
    372       _Ptr             _M_ptr;  // copy constructor must not throw
    373       _My_Deleter      _M_del;  // copy constructor must not throw
    374     };
    375 
    376   // helpers for make_shared / allocate_shared
    377 
    378   template<typename _Tp>
    379     struct _Sp_destroy_inplace
    380     {
    381       void operator()(_Tp* __p) const { if (__p) __p->~_Tp(); }
    382     };
    383 
    384   struct _Sp_make_shared_tag { };
    385 
    386   template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
    387     class _Sp_counted_ptr_inplace
    388     : public _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp>
    389     {
    390       typedef _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp>
    391 	_Base_type;
    392 
    393     public:
    394       explicit
    395       _Sp_counted_ptr_inplace(_Alloc __a)
    396       : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a)
    397       , _M_storage()
    398       {
    399 	void* __p = &_M_storage;
    400 	::new (__p) _Tp();  // might throw
    401 	_Base_type::_M_ptr = static_cast<_Tp*>(__p);
    402       }
    403 
    404       template<typename... _Args>
    405 	_Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
    406 	: _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a)
    407 	, _M_storage()
    408 	{
    409 	  void* __p = &_M_storage;
    410 	  ::new (__p) _Tp(std::forward<_Args>(__args)...);  // might throw
    411 	  _Base_type::_M_ptr = static_cast<_Tp*>(__p);
    412 	}
    413 
    414       // Override because the allocator needs to know the dynamic type
    415       virtual void
    416       _M_destroy() // nothrow
    417       {
    418 	typedef typename _Alloc::template
    419 	    rebind<_Sp_counted_ptr_inplace>::other _My_alloc_type;
    420 	_My_alloc_type __a(_Base_type::_M_del);
    421 	this->~_Sp_counted_ptr_inplace();
    422 	__a.deallocate(this, 1);
    423       }
    424 
    425       // Sneaky trick so __shared_ptr can get the managed pointer
    426       virtual void*
    427       _M_get_deleter(const std::type_info& __ti)
    428       {
    429 #ifdef __GXX_RTTI
    430 	return __ti == typeid(_Sp_make_shared_tag)
    431 	       ? static_cast<void*>(&_M_storage)
    432 	       : _Base_type::_M_get_deleter(__ti);
    433 #else
    434         return 0;
    435 #endif
    436       }
    437 
    438     private:
    439       typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type
    440 	_M_storage;
    441     };
    442 
    443   template<_Lock_policy _Lp>
    444     class __shared_count
    445     {
    446     public:
    447       constexpr __shared_count() : _M_pi(0) // nothrow
    448       { }
    449 
    450       template<typename _Ptr>
    451         explicit
    452 	__shared_count(_Ptr __p) : _M_pi(0)
    453 	{
    454 	  __try
    455 	    {
    456 	      _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
    457 	    }
    458 	  __catch(...)
    459 	    {
    460 	      delete __p;
    461 	      __throw_exception_again;
    462 	    }
    463 	}
    464 
    465       template<typename _Ptr, typename _Deleter>
    466 	__shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
    467 	{
    468 	  // The allocator's value_type doesn't matter, will rebind it anyway.
    469 	  typedef std::allocator<int> _Alloc;
    470 	  typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
    471 	  typedef std::allocator<_Sp_cd_type> _Alloc2;
    472 	  _Alloc2 __a2;
    473 	  __try
    474 	    {
    475 	      _M_pi = __a2.allocate(1);
    476 	      ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d);
    477 	    }
    478 	  __catch(...)
    479 	    {
    480 	      __d(__p); // Call _Deleter on __p.
    481 	      if (_M_pi)
    482 		__a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1);
    483 	      __throw_exception_again;
    484 	    }
    485 	}
    486 
    487       template<typename _Ptr, typename _Deleter, typename _Alloc>
    488 	__shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
    489 	{
    490 	  typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
    491 	  typedef typename _Alloc::template rebind<_Sp_cd_type>::other _Alloc2;
    492 	  _Alloc2 __a2(__a);
    493 	  __try
    494 	    {
    495 	      _M_pi = __a2.allocate(1);
    496 	      ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d, __a);
    497 	    }
    498 	  __catch(...)
    499 	    {
    500 	      __d(__p); // Call _Deleter on __p.
    501 	      if (_M_pi)
    502 		__a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1);
    503 	      __throw_exception_again;
    504 	    }
    505 	}
    506 
    507       template<typename _Tp, typename _Alloc, typename... _Args>
    508 	__shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a,
    509 		       _Args&&... __args)
    510 	: _M_pi(0)
    511 	{
    512 	  typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
    513 	  typedef typename _Alloc::template rebind<_Sp_cp_type>::other _Alloc2;
    514 	  _Alloc2 __a2(__a);
    515 	  __try
    516 	    {
    517 	      _M_pi = __a2.allocate(1);
    518 	      ::new(static_cast<void*>(_M_pi)) _Sp_cp_type(__a,
    519 		    std::forward<_Args>(__args)...);
    520 	    }
    521 	  __catch(...)
    522 	    {
    523 	      if (_M_pi)
    524 		__a2.deallocate(static_cast<_Sp_cp_type*>(_M_pi), 1);
    525 	      __throw_exception_again;
    526 	    }
    527 	}
    528 
    529 #if _GLIBCXX_USE_DEPRECATED
    530       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
    531       template<typename _Tp>
    532         explicit
    533 	__shared_count(std::auto_ptr<_Tp>&& __r)
    534 	: _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get()))
    535 	{ __r.release(); }
    536 #endif
    537 
    538       // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
    539       template<typename _Tp, typename _Del>
    540         explicit
    541 	__shared_count(std::unique_ptr<_Tp, _Del>&& __r)
    542 	: _M_pi(_S_create_from_up(std::move(__r)))
    543 	{ __r.release(); }
    544 
    545       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
    546       explicit __shared_count(const __weak_count<_Lp>& __r);
    547 
    548       ~__shared_count() // nothrow
    549       {
    550 	if (_M_pi != 0)
    551 	  _M_pi->_M_release();
    552       }
    553 
    554       __shared_count(const __shared_count& __r)
    555       : _M_pi(__r._M_pi) // nothrow
    556       {
    557 	if (_M_pi != 0)
    558 	  _M_pi->_M_add_ref_copy();
    559       }
    560 
    561       __shared_count&
    562       operator=(const __shared_count& __r) // nothrow
    563       {
    564 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    565 	if (__tmp != _M_pi)
    566 	  {
    567 	    if (__tmp != 0)
    568 	      __tmp->_M_add_ref_copy();
    569 	    if (_M_pi != 0)
    570 	      _M_pi->_M_release();
    571 	    _M_pi = __tmp;
    572 	  }
    573 	return *this;
    574       }
    575 
    576       void
    577       _M_swap(__shared_count& __r) // nothrow
    578       {
    579 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    580 	__r._M_pi = _M_pi;
    581 	_M_pi = __tmp;
    582       }
    583 
    584       long
    585       _M_get_use_count() const // nothrow
    586       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
    587 
    588       bool
    589       _M_unique() const // nothrow
    590       { return this->_M_get_use_count() == 1; }
    591 
    592       void*
    593       _M_get_deleter(const std::type_info& __ti) const
    594       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
    595 
    596       bool
    597       _M_less(const __shared_count& __rhs) const
    598       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
    599 
    600       bool
    601       _M_less(const __weak_count<_Lp>& __rhs) const
    602       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
    603 
    604       // Friend function injected into enclosing namespace and found by ADL
    605       friend inline bool
    606       operator==(const __shared_count& __a, const __shared_count& __b)
    607       { return __a._M_pi == __b._M_pi; }
    608 
    609     private:
    610       friend class __weak_count<_Lp>;
    611 
    612       template<typename _Tp, typename _Del>
    613 	static _Sp_counted_base<_Lp>*
    614 	_S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
    615 	  typename std::enable_if<!std::is_reference<_Del>::value>::type* = 0)
    616 	{
    617 	  return new _Sp_counted_deleter<_Tp*, _Del, std::allocator<_Tp>,
    618 	    _Lp>(__r.get(), __r.get_deleter());
    619 	}
    620 
    621       template<typename _Tp, typename _Del>
    622 	static _Sp_counted_base<_Lp>*
    623 	_S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
    624 	  typename std::enable_if<std::is_reference<_Del>::value>::type* = 0)
    625 	{
    626 	  typedef typename std::remove_reference<_Del>::type _Del1;
    627 	  typedef std::reference_wrapper<_Del1> _Del2;
    628 	  return new _Sp_counted_deleter<_Tp*, _Del2, std::allocator<_Tp>,
    629 	    _Lp>(__r.get(), std::ref(__r.get_deleter()));
    630 	}
    631 
    632       _Sp_counted_base<_Lp>*  _M_pi;
    633     };
    634 
    635 
    636   template<_Lock_policy _Lp>
    637     class __weak_count
    638     {
    639     public:
    640       constexpr __weak_count() : _M_pi(0) // nothrow
    641       { }
    642 
    643       __weak_count(const __shared_count<_Lp>& __r) : _M_pi(__r._M_pi) // nothrow
    644       {
    645 	if (_M_pi != 0)
    646 	  _M_pi->_M_weak_add_ref();
    647       }
    648 
    649       __weak_count(const __weak_count<_Lp>& __r) : _M_pi(__r._M_pi) // nothrow
    650       {
    651 	if (_M_pi != 0)
    652 	  _M_pi->_M_weak_add_ref();
    653       }
    654 
    655       ~__weak_count() // nothrow
    656       {
    657 	if (_M_pi != 0)
    658 	  _M_pi->_M_weak_release();
    659       }
    660 
    661       __weak_count<_Lp>&
    662       operator=(const __shared_count<_Lp>& __r) // nothrow
    663       {
    664 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    665 	if (__tmp != 0)
    666 	  __tmp->_M_weak_add_ref();
    667 	if (_M_pi != 0)
    668 	  _M_pi->_M_weak_release();
    669 	_M_pi = __tmp;
    670 	return *this;
    671       }
    672 
    673       __weak_count<_Lp>&
    674       operator=(const __weak_count<_Lp>& __r) // nothrow
    675       {
    676 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    677 	if (__tmp != 0)
    678 	  __tmp->_M_weak_add_ref();
    679 	if (_M_pi != 0)
    680 	  _M_pi->_M_weak_release();
    681 	_M_pi = __tmp;
    682 	return *this;
    683       }
    684 
    685       void
    686       _M_swap(__weak_count<_Lp>& __r) // nothrow
    687       {
    688 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    689 	__r._M_pi = _M_pi;
    690 	_M_pi = __tmp;
    691       }
    692 
    693       long
    694       _M_get_use_count() const // nothrow
    695       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
    696 
    697       bool
    698       _M_less(const __weak_count& __rhs) const
    699       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
    700 
    701       bool
    702       _M_less(const __shared_count<_Lp>& __rhs) const
    703       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
    704 
    705       // Friend function injected into enclosing namespace and found by ADL
    706       friend inline bool
    707       operator==(const __weak_count& __a, const __weak_count& __b)
    708       { return __a._M_pi == __b._M_pi; }
    709 
    710     private:
    711       friend class __shared_count<_Lp>;
    712 
    713       _Sp_counted_base<_Lp>*  _M_pi;
    714     };
    715 
    716   // Now that __weak_count is defined we can define this constructor:
    717   template<_Lock_policy _Lp>
    718     inline __shared_count<_Lp>:: __shared_count(const __weak_count<_Lp>& __r)
    719     : _M_pi(__r._M_pi)
    720     {
    721       if (_M_pi != 0)
    722 	_M_pi->_M_add_ref_lock();
    723       else
    724 	__throw_bad_weak_ptr();
    725     }
    726 
    727 
    728   // Support for enable_shared_from_this.
    729 
    730   // Friend of __enable_shared_from_this.
    731   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
    732     void
    733     __enable_shared_from_this_helper(const __shared_count<_Lp>&,
    734 				     const __enable_shared_from_this<_Tp1,
    735 				     _Lp>*, const _Tp2*);
    736 
    737   // Friend of enable_shared_from_this.
    738   template<typename _Tp1, typename _Tp2>
    739     void
    740     __enable_shared_from_this_helper(const __shared_count<>&,
    741 				     const enable_shared_from_this<_Tp1>*,
    742 				     const _Tp2*);
    743 
    744   template<_Lock_policy _Lp>
    745     inline void
    746     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
    747     { }
    748 
    749 
    750   template<typename _Tp, _Lock_policy _Lp>
    751     class __shared_ptr
    752     {
    753     public:
    754       typedef _Tp   element_type;
    755 
    756       constexpr __shared_ptr()
    757       : _M_ptr(0), _M_refcount() // never throws
    758       { }
    759 
    760       template<typename _Tp1>
    761 	explicit __shared_ptr(_Tp1* __p)
    762         : _M_ptr(__p), _M_refcount(__p)
    763 	{
    764 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    765 	  static_assert( sizeof(_Tp1) > 0, "incomplete type" );
    766 	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
    767 	}
    768 
    769       template<typename _Tp1, typename _Deleter>
    770 	__shared_ptr(_Tp1* __p, _Deleter __d)
    771 	: _M_ptr(__p), _M_refcount(__p, __d)
    772 	{
    773 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    774 	  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
    775 	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
    776 	}
    777 
    778       template<typename _Tp1, typename _Deleter, typename _Alloc>
    779 	__shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
    780 	: _M_ptr(__p), _M_refcount(__p, __d, std::move(__a))
    781 	{
    782 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    783 	  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
    784 	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
    785 	}
    786 
    787       template<typename _Deleter>
    788 	__shared_ptr(nullptr_t __p, _Deleter __d)
    789 	: _M_ptr(0), _M_refcount(__p, __d)
    790 	{ }
    791 
    792       template<typename _Deleter, typename _Alloc>
    793         __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
    794 	: _M_ptr(0), _M_refcount(__p, __d, std::move(__a))
    795 	{ }
    796 
    797       template<typename _Tp1>
    798 	__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p)
    799 	: _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
    800 	{ }
    801 
    802       __shared_ptr(const __shared_ptr&) = default; // never throws
    803       __shared_ptr& operator=(const __shared_ptr&) = default; // never throws
    804 
    805       template<typename _Tp1, typename = typename
    806 	       std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
    807 	__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
    808 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    809 	{ }
    810 
    811       __shared_ptr(__shared_ptr&& __r)
    812       : _M_ptr(__r._M_ptr), _M_refcount() // never throws
    813       {
    814 	_M_refcount._M_swap(__r._M_refcount);
    815 	__r._M_ptr = 0;
    816       }
    817 
    818       template<typename _Tp1, typename = typename
    819 	       std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
    820 	__shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r)
    821 	: _M_ptr(__r._M_ptr), _M_refcount() // never throws
    822 	{
    823 	  _M_refcount._M_swap(__r._M_refcount);
    824 	  __r._M_ptr = 0;
    825 	}
    826 
    827       template<typename _Tp1>
    828 	explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    829 	: _M_refcount(__r._M_refcount) // may throw
    830 	{
    831 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    832 
    833 	  // It is now safe to copy __r._M_ptr, as
    834 	  // _M_refcount(__r._M_refcount) did not throw.
    835 	  _M_ptr = __r._M_ptr;
    836 	}
    837 
    838       // If an exception is thrown this constructor has no effect.
    839       template<typename _Tp1, typename _Del>
    840 	__shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
    841 	: _M_ptr(__r.get()), _M_refcount()
    842 	{
    843 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    844 	  _Tp1* __tmp = __r.get();
    845 	  _M_refcount = __shared_count<_Lp>(std::move(__r));
    846 	  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
    847 	}
    848 
    849 #if _GLIBCXX_USE_DEPRECATED
    850       // Postcondition: use_count() == 1 and __r.get() == 0
    851       template<typename _Tp1>
    852 	__shared_ptr(std::auto_ptr<_Tp1>&& __r)
    853 	: _M_ptr(__r.get()), _M_refcount()
    854 	{
    855 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    856 	  static_assert( sizeof(_Tp1) > 0, "incomplete type" );
    857 	  _Tp1* __tmp = __r.get();
    858 	  _M_refcount = __shared_count<_Lp>(std::move(__r));
    859 	  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
    860 	}
    861 #endif
    862 
    863       /* TODO: use delegating constructor */
    864       constexpr __shared_ptr(nullptr_t)
    865       : _M_ptr(0), _M_refcount() // never throws
    866       { }
    867 
    868       template<typename _Tp1>
    869 	__shared_ptr&
    870 	operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
    871 	{
    872 	  _M_ptr = __r._M_ptr;
    873 	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
    874 	  return *this;
    875 	}
    876 
    877 #if _GLIBCXX_USE_DEPRECATED
    878       template<typename _Tp1>
    879 	__shared_ptr&
    880 	operator=(std::auto_ptr<_Tp1>&& __r)
    881 	{
    882 	  __shared_ptr(std::move(__r)).swap(*this);
    883 	  return *this;
    884 	}
    885 #endif
    886 
    887       __shared_ptr&
    888       operator=(__shared_ptr&& __r)
    889       {
    890 	__shared_ptr(std::move(__r)).swap(*this);
    891 	return *this;
    892       }
    893 
    894       template<class _Tp1>
    895 	__shared_ptr&
    896 	operator=(__shared_ptr<_Tp1, _Lp>&& __r)
    897 	{
    898 	  __shared_ptr(std::move(__r)).swap(*this);
    899 	  return *this;
    900 	}
    901 
    902       template<typename _Tp1, typename _Del>
    903 	__shared_ptr&
    904 	operator=(std::unique_ptr<_Tp1, _Del>&& __r)
    905 	{
    906 	  __shared_ptr(std::move(__r)).swap(*this);
    907 	  return *this;
    908 	}
    909 
    910       void
    911       reset() // never throws
    912       { __shared_ptr().swap(*this); }
    913 
    914       template<typename _Tp1>
    915 	void
    916 	reset(_Tp1* __p) // _Tp1 must be complete.
    917 	{
    918 	  // Catch self-reset errors.
    919 	  _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
    920 	  __shared_ptr(__p).swap(*this);
    921 	}
    922 
    923       template<typename _Tp1, typename _Deleter>
    924 	void
    925 	reset(_Tp1* __p, _Deleter __d)
    926 	{ __shared_ptr(__p, __d).swap(*this); }
    927 
    928       template<typename _Tp1, typename _Deleter, typename _Alloc>
    929 	void
    930         reset(_Tp1* __p, _Deleter __d, _Alloc __a)
    931         { __shared_ptr(__p, __d, std::move(__a)).swap(*this); }
    932 
    933       // Allow class instantiation when _Tp is [cv-qual] void.
    934       typename std::add_lvalue_reference<_Tp>::type
    935       operator*() const // never throws
    936       {
    937 	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    938 	return *_M_ptr;
    939       }
    940 
    941       _Tp*
    942       operator->() const // never throws
    943       {
    944 	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    945 	return _M_ptr;
    946       }
    947 
    948       _Tp*
    949       get() const // never throws
    950       { return _M_ptr; }
    951 
    952       explicit operator bool() const // never throws
    953       { return _M_ptr == 0 ? false : true; }
    954 
    955       bool
    956       unique() const // never throws
    957       { return _M_refcount._M_unique(); }
    958 
    959       long
    960       use_count() const // never throws
    961       { return _M_refcount._M_get_use_count(); }
    962 
    963       void
    964       swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
    965       {
    966 	std::swap(_M_ptr, __other._M_ptr);
    967 	_M_refcount._M_swap(__other._M_refcount);
    968       }
    969 
    970       template<typename _Tp1>
    971 	bool
    972 	owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const
    973 	{ return _M_refcount._M_less(__rhs._M_refcount); }
    974 
    975       template<typename _Tp1>
    976 	bool
    977 	owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const
    978 	{ return _M_refcount._M_less(__rhs._M_refcount); }
    979 
    980 #ifdef __GXX_RTTI
    981     protected:
    982       // This constructor is non-standard, it is used by allocate_shared.
    983       template<typename _Alloc, typename... _Args>
    984 	__shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
    985 		     _Args&&... __args)
    986 	: _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
    987 				std::forward<_Args>(__args)...)
    988 	{
    989 	  // _M_ptr needs to point to the newly constructed object.
    990 	  // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
    991 	  void* __p = _M_refcount._M_get_deleter(typeid(__tag));
    992 	  _M_ptr = static_cast<_Tp*>(__p);
    993 	  __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
    994 	}
    995 #else
    996       template<typename _Alloc>
    997         struct _Deleter
    998         {
    999           void operator()(_Tp* __ptr)
   1000           {
   1001             _M_alloc.destroy(__ptr);
   1002             _M_alloc.deallocate(__ptr, 1);
   1003           }
   1004           _Alloc _M_alloc;
   1005         };
   1006 
   1007       template<typename _Alloc, typename... _Args>
   1008 	__shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
   1009 		     _Args&&... __args)
   1010 	: _M_ptr(), _M_refcount()
   1011         {
   1012 	  typedef typename _Alloc::template rebind<_Tp>::other _Alloc2;
   1013           _Deleter<_Alloc2> __del = { _Alloc2(__a) };
   1014           _M_ptr = __del._M_alloc.allocate(1);
   1015 	  __try
   1016 	    {
   1017               __del._M_alloc.construct(_M_ptr, std::forward<_Args>(__args)...);
   1018 	    }
   1019 	  __catch(...)
   1020 	    {
   1021               __del._M_alloc.deallocate(_M_ptr, 1);
   1022 	      __throw_exception_again;
   1023 	    }
   1024           __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);
   1025           _M_refcount._M_swap(__count);
   1026 	  __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
   1027         }
   1028 #endif
   1029 
   1030       template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
   1031 	       typename... _Args>
   1032 	friend __shared_ptr<_Tp1, _Lp1>
   1033 	__allocate_shared(const _Alloc& __a, _Args&&... __args);
   1034 
   1035     private:
   1036       void*
   1037       _M_get_deleter(const std::type_info& __ti) const
   1038       { return _M_refcount._M_get_deleter(__ti); }
   1039 
   1040       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
   1041       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
   1042 
   1043       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
   1044 	friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
   1045 
   1046       _Tp*	   	   _M_ptr;         // Contained pointer.
   1047       __shared_count<_Lp>  _M_refcount;    // Reference counter.
   1048     };
   1049 
   1050 
   1051   // 20.8.13.2.7 shared_ptr comparisons
   1052   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
   1053     inline bool
   1054     operator==(const __shared_ptr<_Tp1, _Lp>& __a,
   1055 	       const __shared_ptr<_Tp2, _Lp>& __b)
   1056     { return __a.get() == __b.get(); }
   1057 
   1058   template<typename _Tp, _Lock_policy _Lp>
   1059     inline bool
   1060     operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t)
   1061     { return __a.get() == nullptr; }
   1062 
   1063   template<typename _Tp, _Lock_policy _Lp>
   1064     inline bool
   1065     operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __b)
   1066     { return nullptr == __b.get(); }
   1067 
   1068   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
   1069     inline bool
   1070     operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
   1071 	       const __shared_ptr<_Tp2, _Lp>& __b)
   1072     { return __a.get() != __b.get(); }
   1073 
   1074   template<typename _Tp, _Lock_policy _Lp>
   1075     inline bool
   1076     operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t)
   1077     { return __a.get() != nullptr; }
   1078 
   1079   template<typename _Tp, _Lock_policy _Lp>
   1080     inline bool
   1081     operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __b)
   1082     { return nullptr != __b.get(); }
   1083 
   1084   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
   1085     inline bool
   1086     operator<(const __shared_ptr<_Tp1, _Lp>& __a,
   1087 	      const __shared_ptr<_Tp2, _Lp>& __b)
   1088     { return __a.get() < __b.get(); }
   1089 
   1090   template<typename _Sp>
   1091     struct _Sp_less : public binary_function<_Sp, _Sp, bool>
   1092     {
   1093       bool
   1094       operator()(const _Sp& __lhs, const _Sp& __rhs) const
   1095       {
   1096 	typedef typename _Sp::element_type element_type;
   1097 	return std::less<element_type*>()(__lhs.get(), __rhs.get());
   1098       }
   1099     };
   1100 
   1101   template<typename _Tp, _Lock_policy _Lp>
   1102     struct less<__shared_ptr<_Tp, _Lp>>
   1103     : public _Sp_less<__shared_ptr<_Tp, _Lp>>
   1104     { };
   1105 
   1106   // 2.2.3.8 shared_ptr specialized algorithms.
   1107   template<typename _Tp, _Lock_policy _Lp>
   1108     inline void
   1109     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
   1110     { __a.swap(__b); }
   1111 
   1112   // 2.2.3.9 shared_ptr casts
   1113 
   1114   // The seemingly equivalent code:
   1115   // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
   1116   // will eventually result in undefined behaviour, attempting to
   1117   // delete the same object twice.
   1118   /// static_pointer_cast
   1119   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
   1120     inline __shared_ptr<_Tp, _Lp>
   1121     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
   1122     { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
   1123 
   1124   // The seemingly equivalent code:
   1125   // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
   1126   // will eventually result in undefined behaviour, attempting to
   1127   // delete the same object twice.
   1128   /// const_pointer_cast
   1129   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
   1130     inline __shared_ptr<_Tp, _Lp>
   1131     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
   1132     { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
   1133 
   1134   // The seemingly equivalent code:
   1135   // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
   1136   // will eventually result in undefined behaviour, attempting to
   1137   // delete the same object twice.
   1138   /// dynamic_pointer_cast
   1139   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
   1140     inline __shared_ptr<_Tp, _Lp>
   1141     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
   1142     {
   1143       if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
   1144 	return __shared_ptr<_Tp, _Lp>(__r, __p);
   1145       return __shared_ptr<_Tp, _Lp>();
   1146     }
   1147 
   1148 
   1149   template<typename _Tp, _Lock_policy _Lp>
   1150     class __weak_ptr
   1151     {
   1152     public:
   1153       typedef _Tp element_type;
   1154 
   1155       constexpr __weak_ptr()
   1156       : _M_ptr(0), _M_refcount() // never throws
   1157       { }
   1158 
   1159       // Generated copy constructor, assignment, destructor are fine.
   1160 
   1161       // The "obvious" converting constructor implementation:
   1162       //
   1163       //  template<typename _Tp1>
   1164       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
   1165       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
   1166       //    { }
   1167       //
   1168       // has a serious problem.
   1169       //
   1170       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
   1171       //  conversion may require access to *__r._M_ptr (virtual inheritance).
   1172       //
   1173       // It is not possible to avoid spurious access violations since
   1174       // in multithreaded programs __r._M_ptr may be invalidated at any point.
   1175       template<typename _Tp1, typename = typename
   1176 	       std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
   1177 	__weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
   1178 	: _M_refcount(__r._M_refcount) // never throws
   1179         { _M_ptr = __r.lock().get(); }
   1180 
   1181       template<typename _Tp1, typename = typename
   1182 	       std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
   1183 	__weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
   1184 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
   1185 	{ }
   1186 
   1187       template<typename _Tp1>
   1188 	__weak_ptr&
   1189 	operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
   1190 	{
   1191 	  _M_ptr = __r.lock().get();
   1192 	  _M_refcount = __r._M_refcount;
   1193 	  return *this;
   1194 	}
   1195 
   1196       template<typename _Tp1>
   1197 	__weak_ptr&
   1198 	operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
   1199 	{
   1200 	  _M_ptr = __r._M_ptr;
   1201 	  _M_refcount = __r._M_refcount;
   1202 	  return *this;
   1203 	}
   1204 
   1205       __shared_ptr<_Tp, _Lp>
   1206       lock() const // never throws
   1207       {
   1208 #ifdef __GTHREADS
   1209 	// Optimization: avoid throw overhead.
   1210 	if (expired())
   1211 	  return __shared_ptr<element_type, _Lp>();
   1212 
   1213 	__try
   1214 	  {
   1215 	    return __shared_ptr<element_type, _Lp>(*this);
   1216 	  }
   1217 	__catch(const bad_weak_ptr&)
   1218 	  {
   1219 	    // Q: How can we get here?
   1220 	    // A: Another thread may have invalidated r after the
   1221 	    //    use_count test above.
   1222 	    return __shared_ptr<element_type, _Lp>();
   1223 	  }
   1224 
   1225 #else
   1226 	// Optimization: avoid try/catch overhead when single threaded.
   1227 	return expired() ? __shared_ptr<element_type, _Lp>()
   1228 			 : __shared_ptr<element_type, _Lp>(*this);
   1229 
   1230 #endif
   1231       } // XXX MT
   1232 
   1233       long
   1234       use_count() const // never throws
   1235       { return _M_refcount._M_get_use_count(); }
   1236 
   1237       bool
   1238       expired() const // never throws
   1239       { return _M_refcount._M_get_use_count() == 0; }
   1240 
   1241       template<typename _Tp1>
   1242 	bool
   1243 	owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const
   1244 	{ return _M_refcount._M_less(__rhs._M_refcount); }
   1245 
   1246       template<typename _Tp1>
   1247 	bool
   1248 	owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const
   1249 	{ return _M_refcount._M_less(__rhs._M_refcount); }
   1250 
   1251       void
   1252       reset() // never throws
   1253       { __weak_ptr().swap(*this); }
   1254 
   1255       void
   1256       swap(__weak_ptr& __s) // never throws
   1257       {
   1258 	std::swap(_M_ptr, __s._M_ptr);
   1259 	_M_refcount._M_swap(__s._M_refcount);
   1260       }
   1261 
   1262     private:
   1263       // Used by __enable_shared_from_this.
   1264       void
   1265       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
   1266       {
   1267 	_M_ptr = __ptr;
   1268 	_M_refcount = __refcount;
   1269       }
   1270 
   1271       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
   1272       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
   1273       friend class __enable_shared_from_this<_Tp, _Lp>;
   1274       friend class enable_shared_from_this<_Tp>;
   1275 
   1276       _Tp*	 	 _M_ptr;         // Contained pointer.
   1277       __weak_count<_Lp>  _M_refcount;    // Reference counter.
   1278     };
   1279 
   1280   // 20.8.13.3.7 weak_ptr specialized algorithms.
   1281   template<typename _Tp, _Lock_policy _Lp>
   1282     inline void
   1283     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
   1284     { __a.swap(__b); }
   1285 
   1286   template<typename _Tp, typename _Tp1>
   1287     struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
   1288     {
   1289       bool
   1290       operator()(const _Tp& __lhs, const _Tp& __rhs) const
   1291       { return __lhs.owner_before(__rhs); }
   1292 
   1293       bool
   1294       operator()(const _Tp& __lhs, const _Tp1& __rhs) const
   1295       { return __lhs.owner_before(__rhs); }
   1296 
   1297       bool
   1298       operator()(const _Tp1& __lhs, const _Tp& __rhs) const
   1299       { return __lhs.owner_before(__rhs); }
   1300     };
   1301 
   1302   template<typename _Tp, _Lock_policy _Lp>
   1303     struct owner_less<__shared_ptr<_Tp, _Lp>>
   1304     : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
   1305     { };
   1306 
   1307   template<typename _Tp, _Lock_policy _Lp>
   1308     struct owner_less<__weak_ptr<_Tp, _Lp>>
   1309     : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
   1310     { };
   1311 
   1312 
   1313   template<typename _Tp, _Lock_policy _Lp>
   1314     class __enable_shared_from_this
   1315     {
   1316     protected:
   1317       constexpr __enable_shared_from_this() { }
   1318 
   1319       __enable_shared_from_this(const __enable_shared_from_this&) { }
   1320 
   1321       __enable_shared_from_this&
   1322       operator=(const __enable_shared_from_this&)
   1323       { return *this; }
   1324 
   1325       ~__enable_shared_from_this() { }
   1326 
   1327     public:
   1328       __shared_ptr<_Tp, _Lp>
   1329       shared_from_this()
   1330       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
   1331 
   1332       __shared_ptr<const _Tp, _Lp>
   1333       shared_from_this() const
   1334       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
   1335 
   1336     private:
   1337       template<typename _Tp1>
   1338 	void
   1339 	_M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
   1340 	{ _M_weak_this._M_assign(__p, __n); }
   1341 
   1342       template<typename _Tp1>
   1343 	friend void
   1344 	__enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
   1345 					 const __enable_shared_from_this* __pe,
   1346 					 const _Tp1* __px)
   1347 	{
   1348 	  if (__pe != 0)
   1349 	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
   1350 	}
   1351 
   1352       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
   1353     };
   1354 
   1355 
   1356   template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
   1357     inline __shared_ptr<_Tp, _Lp>
   1358     __allocate_shared(const _Alloc& __a, _Args&&... __args)
   1359     {
   1360       return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a,
   1361 				    std::forward<_Args>(__args)...);
   1362     }
   1363 
   1364   template<typename _Tp, _Lock_policy _Lp, typename... _Args>
   1365     inline __shared_ptr<_Tp, _Lp>
   1366     __make_shared(_Args&&... __args)
   1367     {
   1368       typedef typename std::remove_const<_Tp>::type _Tp_nc;
   1369       return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
   1370 					      std::forward<_Args>(__args)...);
   1371     }
   1372 
   1373   /// std::hash specialization for __shared_ptr.
   1374   template<typename _Tp, _Lock_policy _Lp>
   1375     struct hash<__shared_ptr<_Tp, _Lp>>
   1376     : public std::unary_function<__shared_ptr<_Tp, _Lp>, size_t>
   1377     {
   1378       size_t
   1379       operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
   1380       { return std::hash<_Tp*>()(__s.get()); }
   1381     };
   1382 
   1383 _GLIBCXX_END_NAMESPACE_VERSION
   1384 } // namespace
   1385 
   1386 #endif // _SHARED_PTR_BASE_H
   1387