(root)/
gcc-13.2.0/
libstdc++-v3/
include/
tr1/
shared_ptr.h
       1  // <tr1/shared_ptr.h> -*- C++ -*-
       2  
       3  // Copyright (C) 2007-2023 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  //  shared_count.hpp
      26  //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
      27  
      28  //  shared_ptr.hpp
      29  //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
      30  //  Copyright (C) 2001, 2002, 2003 Peter Dimov
      31  
      32  //  weak_ptr.hpp
      33  //  Copyright (C) 2001, 2002, 2003 Peter Dimov
      34  
      35  //  enable_shared_from_this.hpp
      36  //  Copyright (C) 2002 Peter Dimov
      37  
      38  // Distributed under the Boost Software License, Version 1.0. (See
      39  // accompanying file LICENSE_1_0.txt or copy at
      40  // http://www.boost.org/LICENSE_1_0.txt)
      41  
      42  // GCC Note:  based on version 1.32.0 of the Boost library.
      43  
      44  /** @file tr1/shared_ptr.h
      45   *  This is an internal header file, included by other library headers.
      46   *  Do not attempt to use it directly. @headername{tr1/memory}
      47   */
      48  
      49  #ifndef _TR1_SHARED_PTR_H
      50  #define _TR1_SHARED_PTR_H 1
      51  
      52  namespace std _GLIBCXX_VISIBILITY(default)
      53  {
      54  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      55  
      56  namespace tr1
      57  {
      58   /**
      59     *  @brief  Exception possibly thrown by @c shared_ptr.
      60     *  @ingroup exceptions
      61     */
      62    class bad_weak_ptr : public std::exception
      63    {
      64    public:
      65      virtual char const*
      66      what() const throw()
      67      { return "tr1::bad_weak_ptr"; }
      68    };
      69  
      70    // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
      71    inline void
      72    __throw_bad_weak_ptr()
      73    { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
      74  
      75    using __gnu_cxx::_Lock_policy;
      76    using __gnu_cxx::__default_lock_policy;
      77    using __gnu_cxx::_S_single;
      78    using __gnu_cxx::_S_mutex;
      79    using __gnu_cxx::_S_atomic;
      80  
      81    // Empty helper class except when the template argument is _S_mutex.
      82    template<_Lock_policy _Lp>
      83      class _Mutex_base
      84      {
      85      protected:
      86        // The atomic policy uses fully-fenced builtins, single doesn't care.
      87        enum { _S_need_barriers = 0 };
      88      };
      89  
      90    template<>
      91      class _Mutex_base<_S_mutex>
      92      : public __gnu_cxx::__mutex
      93      {
      94      protected:
      95        // This policy is used when atomic builtins are not available.
      96        // The replacement atomic operations might not have the necessary
      97        // memory barriers.
      98        enum { _S_need_barriers = 1 };
      99      };
     100  
     101    template<_Lock_policy _Lp = __default_lock_policy>
     102      class _Sp_counted_base
     103      : public _Mutex_base<_Lp>
     104      {
     105      public:  
     106        _Sp_counted_base()
     107        : _M_use_count(1), _M_weak_count(1) { }
     108        
     109        virtual
     110        ~_Sp_counted_base() // nothrow 
     111        { }
     112    
     113        // Called when _M_use_count drops to zero, to release the resources
     114        // managed by *this.
     115        virtual void
     116        _M_dispose() = 0; // nothrow
     117        
     118        // Called when _M_weak_count drops to zero.
     119        virtual void
     120        _M_destroy() // nothrow
     121        { delete this; }
     122        
     123        virtual void*
     124        _M_get_deleter(const std::type_info&) = 0;
     125  
     126        void
     127        _M_add_ref_copy()
     128        { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
     129    
     130        void
     131        _M_add_ref_lock();
     132        
     133        void
     134        _M_release() // nothrow
     135        {
     136          // Be race-detector-friendly.  For more info see bits/c++config.
     137          _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
     138  	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
     139  	  {
     140              _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
     141  	    _M_dispose();
     142  	    // There must be a memory barrier between dispose() and destroy()
     143  	    // to ensure that the effects of dispose() are observed in the
     144  	    // thread that runs destroy().
     145  	    // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
     146  	    if (_Mutex_base<_Lp>::_S_need_barriers)
     147  	      {
     148  		__atomic_thread_fence (__ATOMIC_ACQ_REL);
     149  	      }
     150  
     151              // Be race-detector-friendly.  For more info see bits/c++config.
     152              _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
     153  	    if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
     154  						       -1) == 1)
     155                {
     156                  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
     157  	        _M_destroy();
     158                }
     159  	  }
     160        }
     161    
     162        void
     163        _M_weak_add_ref() // nothrow
     164        { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
     165  
     166        void
     167        _M_weak_release() // nothrow
     168        {
     169          // Be race-detector-friendly. For more info see bits/c++config.
     170          _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
     171  	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
     172  	  {
     173              _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
     174  	    if (_Mutex_base<_Lp>::_S_need_barriers)
     175  	      {
     176  	        // See _M_release(),
     177  	        // destroy() must observe results of dispose()
     178  		__atomic_thread_fence (__ATOMIC_ACQ_REL);
     179  	      }
     180  	    _M_destroy();
     181  	  }
     182        }
     183    
     184        long
     185        _M_get_use_count() const // nothrow
     186        {
     187          // No memory barrier is used here so there is no synchronization
     188          // with other threads.
     189          return const_cast<const volatile _Atomic_word&>(_M_use_count);
     190        }
     191  
     192      private:  
     193        _Sp_counted_base(_Sp_counted_base const&);
     194        _Sp_counted_base& operator=(_Sp_counted_base const&);
     195  
     196        _Atomic_word  _M_use_count;     // #shared
     197        _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
     198      };
     199  
     200    template<>
     201      inline void
     202      _Sp_counted_base<_S_single>::
     203      _M_add_ref_lock()
     204      {
     205        if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
     206  	{
     207  	  _M_use_count = 0;
     208  	  __throw_bad_weak_ptr();
     209  	}
     210      }
     211  
     212    template<>
     213      inline void
     214      _Sp_counted_base<_S_mutex>::
     215      _M_add_ref_lock()
     216      {
     217        __gnu_cxx::__scoped_lock sentry(*this);
     218        if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
     219  	{
     220  	  _M_use_count = 0;
     221  	  __throw_bad_weak_ptr();
     222  	}
     223      }
     224  
     225    template<> 
     226      inline void
     227      _Sp_counted_base<_S_atomic>::
     228      _M_add_ref_lock()
     229      {
     230        // Perform lock-free add-if-not-zero operation.
     231        _Atomic_word __count = _M_use_count;
     232        do
     233  	{
     234  	  if (__count == 0)
     235  	    __throw_bad_weak_ptr();
     236  	  // Replace the current counter value with the old value + 1, as
     237  	  // long as it's not changed meanwhile. 
     238  	}
     239        while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
     240  					  true, __ATOMIC_ACQ_REL, 
     241  					  __ATOMIC_RELAXED));
     242       }
     243  
     244    template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
     245      class _Sp_counted_base_impl
     246      : public _Sp_counted_base<_Lp>
     247      {
     248      public:
     249        // Precondition: __d(__p) must not throw.
     250        _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
     251        : _M_ptr(__p), _M_del(__d) { }
     252      
     253        virtual void
     254        _M_dispose() // nothrow
     255        { _M_del(_M_ptr); }
     256        
     257        virtual void*
     258        _M_get_deleter(const std::type_info& __ti)
     259        {
     260  #if __cpp_rtti
     261          return __ti == typeid(_Deleter) ? &_M_del : 0;
     262  #else
     263          return 0;
     264  #endif
     265        }
     266        
     267      private:
     268        _Sp_counted_base_impl(const _Sp_counted_base_impl&);
     269        _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
     270        
     271        _Ptr      _M_ptr;  // copy constructor must not throw
     272        _Deleter  _M_del;  // copy constructor must not throw
     273      };
     274  
     275    template<_Lock_policy _Lp = __default_lock_policy>
     276      class __weak_count;
     277  
     278    template<typename _Tp>
     279      struct _Sp_deleter
     280      {
     281        typedef void result_type;
     282        typedef _Tp* argument_type;
     283        void operator()(_Tp* __p) const { delete __p; }
     284      };
     285  
     286    template<_Lock_policy _Lp = __default_lock_policy>
     287      class __shared_count
     288      {
     289      public: 
     290        __shared_count()
     291        : _M_pi(0) // nothrow
     292        { }
     293    
     294        template<typename _Ptr>
     295          __shared_count(_Ptr __p) : _M_pi(0)
     296          {
     297  	  __try
     298  	    {
     299  	      typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
     300  	      _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
     301  	          __p, _Sp_deleter<_Tp>());
     302  	    }
     303  	  __catch(...)
     304  	    {
     305  	      delete __p;
     306  	      __throw_exception_again;
     307  	    }
     308  	}
     309  
     310        template<typename _Ptr, typename _Deleter>
     311          __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
     312          {
     313  	  __try
     314  	    {
     315  	      _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
     316  	    }
     317  	  __catch(...)
     318  	    {
     319  	      __d(__p); // Call _Deleter on __p.
     320  	      __throw_exception_again;
     321  	    }
     322  	}
     323  
     324  #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
     325  #pragma GCC diagnostic push
     326  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     327        // Special case for auto_ptr<_Tp> to provide the strong guarantee.
     328        template<typename _Tp>
     329          explicit
     330          __shared_count(std::auto_ptr<_Tp>& __r)
     331  	: _M_pi(new _Sp_counted_base_impl<_Tp*,
     332  		_Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
     333          { __r.release(); }
     334  #pragma GCC diagnostic pop
     335  #endif
     336  
     337        // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
     338        explicit
     339        __shared_count(const __weak_count<_Lp>& __r);
     340    
     341        ~__shared_count() // nothrow
     342        {
     343  	if (_M_pi != 0)
     344  	  _M_pi->_M_release();
     345        }
     346        
     347        __shared_count(const __shared_count& __r)
     348        : _M_pi(__r._M_pi) // nothrow
     349        {
     350  	if (_M_pi != 0)
     351  	  _M_pi->_M_add_ref_copy();
     352        }
     353    
     354        __shared_count&
     355        operator=(const __shared_count& __r) // nothrow
     356        {
     357  	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
     358  	if (__tmp != _M_pi)
     359  	  {
     360  	    if (__tmp != 0)
     361  	      __tmp->_M_add_ref_copy();
     362  	    if (_M_pi != 0)
     363  	      _M_pi->_M_release();
     364  	    _M_pi = __tmp;
     365  	  }
     366  	return *this;
     367        }
     368    
     369        void
     370        _M_swap(__shared_count& __r) // nothrow
     371        {
     372  	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
     373  	__r._M_pi = _M_pi;
     374  	_M_pi = __tmp;
     375        }
     376    
     377        long
     378        _M_get_use_count() const // nothrow
     379        { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
     380  
     381        bool
     382        _M_unique() const // nothrow
     383        { return this->_M_get_use_count() == 1; }
     384        
     385        friend inline bool
     386        operator==(const __shared_count& __a, const __shared_count& __b)
     387        { return __a._M_pi == __b._M_pi; }
     388    
     389        friend inline bool
     390        operator<(const __shared_count& __a, const __shared_count& __b)
     391        { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
     392    
     393        void*
     394        _M_get_deleter(const std::type_info& __ti) const
     395        { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
     396  
     397      private:
     398        friend class __weak_count<_Lp>;
     399  
     400        _Sp_counted_base<_Lp>*  _M_pi;
     401      };
     402  
     403  
     404    template<_Lock_policy _Lp>
     405      class __weak_count
     406      {
     407      public:
     408        __weak_count()
     409        : _M_pi(0) // nothrow
     410        { }
     411    
     412        __weak_count(const __shared_count<_Lp>& __r)
     413        : _M_pi(__r._M_pi) // nothrow
     414        {
     415  	if (_M_pi != 0)
     416  	  _M_pi->_M_weak_add_ref();
     417        }
     418        
     419        __weak_count(const __weak_count<_Lp>& __r)
     420        : _M_pi(__r._M_pi) // nothrow
     421        {
     422  	if (_M_pi != 0)
     423  	  _M_pi->_M_weak_add_ref();
     424        }
     425        
     426        ~__weak_count() // nothrow
     427        {
     428  	if (_M_pi != 0)
     429  	  _M_pi->_M_weak_release();
     430        }
     431        
     432        __weak_count<_Lp>&
     433        operator=(const __shared_count<_Lp>& __r) // nothrow
     434        {
     435  	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
     436  	if (__tmp != 0)
     437  	  __tmp->_M_weak_add_ref();
     438  	if (_M_pi != 0)
     439  	  _M_pi->_M_weak_release();
     440  	_M_pi = __tmp;  
     441  	return *this;
     442        }
     443        
     444        __weak_count<_Lp>&
     445        operator=(const __weak_count<_Lp>& __r) // nothrow
     446        {
     447  	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
     448  	if (__tmp != 0)
     449  	  __tmp->_M_weak_add_ref();
     450  	if (_M_pi != 0)
     451  	  _M_pi->_M_weak_release();
     452  	_M_pi = __tmp;
     453  	return *this;
     454        }
     455  
     456        void
     457        _M_swap(__weak_count<_Lp>& __r) // nothrow
     458        {
     459  	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
     460  	__r._M_pi = _M_pi;
     461  	_M_pi = __tmp;
     462        }
     463    
     464        long
     465        _M_get_use_count() const // nothrow
     466        { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
     467  
     468        friend inline bool
     469        operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
     470        { return __a._M_pi == __b._M_pi; }
     471        
     472        friend inline bool
     473        operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
     474        { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
     475  
     476      private:
     477        friend class __shared_count<_Lp>;
     478  
     479        _Sp_counted_base<_Lp>*  _M_pi;
     480      };
     481  
     482    // now that __weak_count is defined we can define this constructor:
     483    template<_Lock_policy _Lp>
     484      inline
     485      __shared_count<_Lp>::
     486      __shared_count(const __weak_count<_Lp>& __r)
     487      : _M_pi(__r._M_pi)
     488      {
     489        if (_M_pi != 0)
     490  	_M_pi->_M_add_ref_lock();
     491        else
     492  	__throw_bad_weak_ptr();
     493      }
     494  
     495    // Forward declarations.
     496    template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
     497      class __shared_ptr;
     498    
     499    template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
     500      class __weak_ptr;
     501  
     502    template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
     503      class __enable_shared_from_this;
     504  
     505    template<typename _Tp>
     506      class shared_ptr;
     507    
     508    template<typename _Tp>
     509      class weak_ptr;
     510  
     511    template<typename _Tp>
     512      class enable_shared_from_this;
     513  
     514    // Support for enable_shared_from_this.
     515  
     516    // Friend of __enable_shared_from_this.
     517    template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
     518      void
     519      __enable_shared_from_this_helper(const __shared_count<_Lp>&,
     520  				     const __enable_shared_from_this<_Tp1,
     521  				     _Lp>*, const _Tp2*);
     522  
     523    // Friend of enable_shared_from_this.
     524    template<typename _Tp1, typename _Tp2>
     525      void
     526      __enable_shared_from_this_helper(const __shared_count<>&,
     527  				     const enable_shared_from_this<_Tp1>*,
     528  				     const _Tp2*);
     529  
     530    template<_Lock_policy _Lp>
     531      inline void
     532      __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
     533      { }
     534  
     535  
     536    struct __static_cast_tag { };
     537    struct __const_cast_tag { };
     538    struct __dynamic_cast_tag { };
     539  
     540    // A smart pointer with reference-counted copy semantics.  The
     541    // object pointed to is deleted when the last shared_ptr pointing to
     542    // it is destroyed or reset.
     543    template<typename _Tp, _Lock_policy _Lp>
     544      class __shared_ptr
     545      {
     546      public:
     547        typedef _Tp   element_type;
     548        
     549        __shared_ptr()
     550        : _M_ptr(0), _M_refcount() // never throws
     551        { }
     552  
     553        template<typename _Tp1>
     554          explicit
     555          __shared_ptr(_Tp1* __p)
     556  	: _M_ptr(__p), _M_refcount(__p)
     557          {
     558  	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
     559  	  typedef int _IsComplete[sizeof(_Tp1)];
     560  	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
     561  	}
     562  
     563        template<typename _Tp1, typename _Deleter>
     564          __shared_ptr(_Tp1* __p, _Deleter __d)
     565          : _M_ptr(__p), _M_refcount(__p, __d)
     566          {
     567  	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
     568  	  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
     569  	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
     570  	}
     571        
     572        //  generated copy constructor, assignment, destructor are fine.
     573        
     574        template<typename _Tp1>
     575          __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
     576  	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
     577          { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
     578  
     579        template<typename _Tp1>
     580          explicit
     581          __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
     582  	: _M_refcount(__r._M_refcount) // may throw
     583          {
     584  	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
     585  	  // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
     586  	  // did not throw.
     587  	  _M_ptr = __r._M_ptr;
     588  	}
     589  
     590  #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
     591  #pragma GCC diagnostic push
     592  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     593        // Postcondition: use_count() == 1 and __r.get() == 0
     594        template<typename _Tp1>
     595          explicit
     596          __shared_ptr(std::auto_ptr<_Tp1>& __r)
     597  	: _M_ptr(__r.get()), _M_refcount()
     598          { // TODO requries delete __r.release() well-formed
     599  	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
     600  	  typedef int _IsComplete[sizeof(_Tp1)];
     601  	  _Tp1* __tmp = __r.get();
     602  	  _M_refcount = __shared_count<_Lp>(__r);
     603  	  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
     604  	}
     605  #pragma GCC diagnostic pop
     606  #endif
     607  
     608        template<typename _Tp1>
     609          __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
     610  	: _M_ptr(static_cast<element_type*>(__r._M_ptr)),
     611  	  _M_refcount(__r._M_refcount)
     612          { }
     613  
     614        template<typename _Tp1>
     615          __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
     616  	: _M_ptr(const_cast<element_type*>(__r._M_ptr)),
     617  	  _M_refcount(__r._M_refcount)
     618          { }
     619  
     620        template<typename _Tp1>
     621          __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
     622  	: _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
     623  	  _M_refcount(__r._M_refcount)
     624          {
     625  	  if (_M_ptr == 0) // need to allocate new counter -- the cast failed
     626  	    _M_refcount = __shared_count<_Lp>();
     627  	}
     628  
     629        template<typename _Tp1>
     630          __shared_ptr&
     631          operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
     632          {
     633  	  _M_ptr = __r._M_ptr;
     634  	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
     635  	  return *this;
     636  	}
     637  
     638  #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
     639  #pragma GCC diagnostic push
     640  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     641        template<typename _Tp1>
     642          __shared_ptr&
     643          operator=(std::auto_ptr<_Tp1>& __r)
     644          {
     645  	  __shared_ptr(__r).swap(*this);
     646  	  return *this;
     647  	}
     648  #pragma GCC diagnostic pop
     649  #endif
     650  
     651        void
     652        reset() // never throws
     653        { __shared_ptr().swap(*this); }
     654  
     655        template<typename _Tp1>
     656          void
     657          reset(_Tp1* __p) // _Tp1 must be complete.
     658          {
     659  	  // Catch self-reset errors.
     660  	  _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 
     661  	  __shared_ptr(__p).swap(*this);
     662  	}
     663  
     664        template<typename _Tp1, typename _Deleter>
     665          void
     666          reset(_Tp1* __p, _Deleter __d)
     667          { __shared_ptr(__p, __d).swap(*this); }
     668  
     669        // Allow class instantiation when _Tp is [cv-qual] void.
     670        typename std::tr1::add_reference<_Tp>::type
     671        operator*() const // never throws
     672        {
     673  	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
     674  	return *_M_ptr;
     675        }
     676  
     677        _Tp*
     678        operator->() const // never throws
     679        {
     680  	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
     681  	return _M_ptr;
     682        }
     683      
     684        _Tp*
     685        get() const // never throws
     686        { return _M_ptr; }
     687  
     688        // Implicit conversion to "bool"
     689      private:
     690        typedef _Tp* __shared_ptr::*__unspecified_bool_type;
     691  
     692      public:
     693        operator __unspecified_bool_type() const // never throws
     694        { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
     695  
     696        bool
     697        unique() const // never throws
     698        { return _M_refcount._M_unique(); }
     699  
     700        long
     701        use_count() const // never throws
     702        { return _M_refcount._M_get_use_count(); }
     703  
     704        void
     705        swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
     706        {
     707  	std::swap(_M_ptr, __other._M_ptr);
     708  	_M_refcount._M_swap(__other._M_refcount);
     709        }
     710  
     711      private:
     712        void*
     713        _M_get_deleter(const std::type_info& __ti) const
     714        { return _M_refcount._M_get_deleter(__ti); }
     715  
     716        template<typename _Tp1, _Lock_policy _Lp1>
     717          bool
     718          _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
     719          { return _M_refcount < __rhs._M_refcount; }
     720  
     721        template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
     722        template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
     723  
     724        template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
     725          friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
     726  
     727        // Friends injected into enclosing namespace and found by ADL:
     728        template<typename _Tp1>
     729          friend inline bool
     730          operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
     731          { return __a.get() == __b.get(); }
     732  
     733        template<typename _Tp1>
     734          friend inline bool
     735          operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
     736          { return __a.get() != __b.get(); }
     737  
     738        template<typename _Tp1>
     739          friend inline bool
     740          operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
     741          { return __a._M_less(__b); }
     742  
     743        _Tp*         	   _M_ptr;         // Contained pointer.
     744        __shared_count<_Lp>  _M_refcount;    // Reference counter.
     745      };
     746  
     747    // 2.2.3.8 shared_ptr specialized algorithms.
     748    template<typename _Tp, _Lock_policy _Lp>
     749      inline void
     750      swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
     751      { __a.swap(__b); }
     752  
     753    // 2.2.3.9 shared_ptr casts
     754    /*  The seemingly equivalent
     755     *           shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
     756     *  will eventually result in undefined behaviour,
     757     *  attempting to delete the same object twice.
     758     */
     759    template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
     760      inline __shared_ptr<_Tp, _Lp>
     761      static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
     762      { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
     763  
     764    /*  The seemingly equivalent
     765     *           shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
     766     *  will eventually result in undefined behaviour,
     767     *  attempting to delete the same object twice.
     768     */
     769    template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
     770      inline __shared_ptr<_Tp, _Lp>
     771      const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
     772      { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
     773  
     774    /*  The seemingly equivalent
     775     *           shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
     776     *  will eventually result in undefined behaviour,
     777     *  attempting to delete the same object twice.
     778     */
     779    template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
     780      inline __shared_ptr<_Tp, _Lp>
     781      dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
     782      { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
     783  
     784    // 2.2.3.7 shared_ptr I/O
     785    template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
     786      std::basic_ostream<_Ch, _Tr>&
     787      operator<<(std::basic_ostream<_Ch, _Tr>& __os, 
     788  	       const __shared_ptr<_Tp, _Lp>& __p)
     789      {
     790        __os << __p.get();
     791        return __os;
     792      }
     793  
     794    // 2.2.3.10 shared_ptr get_deleter (experimental)
     795    template<typename _Del, typename _Tp, _Lock_policy _Lp>
     796      inline _Del*
     797      get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
     798      {
     799  #if __cpp_rtti
     800        return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
     801  #else
     802        return 0;
     803  #endif
     804      }
     805  
     806  
     807    template<typename _Tp, _Lock_policy _Lp>
     808      class __weak_ptr
     809      {
     810      public:
     811        typedef _Tp element_type;
     812        
     813        __weak_ptr()
     814        : _M_ptr(0), _M_refcount() // never throws
     815        { }
     816  
     817        // Generated copy constructor, assignment, destructor are fine.
     818        
     819        // The "obvious" converting constructor implementation:
     820        //
     821        //  template<typename _Tp1>
     822        //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
     823        //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
     824        //    { }
     825        //
     826        // has a serious problem.
     827        //
     828        //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
     829        //  conversion may require access to *__r._M_ptr (virtual inheritance).
     830        //
     831        // It is not possible to avoid spurious access violations since
     832        // in multithreaded programs __r._M_ptr may be invalidated at any point.
     833        template<typename _Tp1>
     834          __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
     835  	: _M_refcount(__r._M_refcount) // never throws
     836          {
     837  	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
     838  	  _M_ptr = __r.lock().get();
     839  	}
     840  
     841        template<typename _Tp1>
     842          __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
     843  	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
     844          { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
     845  
     846        template<typename _Tp1>
     847          __weak_ptr&
     848          operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
     849          {
     850  	  _M_ptr = __r.lock().get();
     851  	  _M_refcount = __r._M_refcount;
     852  	  return *this;
     853  	}
     854        
     855        template<typename _Tp1>
     856          __weak_ptr&
     857          operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
     858          {
     859  	  _M_ptr = __r._M_ptr;
     860  	  _M_refcount = __r._M_refcount;
     861  	  return *this;
     862  	}
     863  
     864        __shared_ptr<_Tp, _Lp>
     865        lock() const // never throws
     866        {
     867  #ifdef __GTHREADS
     868  	// Optimization: avoid throw overhead.
     869  	if (expired())
     870  	  return __shared_ptr<element_type, _Lp>();
     871  
     872  	__try
     873  	  {
     874  	    return __shared_ptr<element_type, _Lp>(*this);
     875  	  }
     876  	__catch(const bad_weak_ptr&)
     877  	  {
     878  	    // Q: How can we get here?
     879  	    // A: Another thread may have invalidated r after the
     880  	    //    use_count test above.
     881  	    return __shared_ptr<element_type, _Lp>();
     882  	  }
     883  	
     884  #else
     885  	// Optimization: avoid try/catch overhead when single threaded.
     886  	return expired() ? __shared_ptr<element_type, _Lp>()
     887  	                 : __shared_ptr<element_type, _Lp>(*this);
     888  
     889  #endif
     890        } // XXX MT
     891  
     892        long
     893        use_count() const // never throws
     894        { return _M_refcount._M_get_use_count(); }
     895  
     896        bool
     897        expired() const // never throws
     898        { return _M_refcount._M_get_use_count() == 0; }
     899        
     900        void
     901        reset() // never throws
     902        { __weak_ptr().swap(*this); }
     903  
     904        void
     905        swap(__weak_ptr& __s) // never throws
     906        {
     907  	std::swap(_M_ptr, __s._M_ptr);
     908  	_M_refcount._M_swap(__s._M_refcount);
     909        }
     910  
     911      private:
     912        // Used by __enable_shared_from_this.
     913        void
     914        _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
     915        {
     916  	_M_ptr = __ptr;
     917  	_M_refcount = __refcount;
     918        }
     919  
     920        template<typename _Tp1>
     921          bool
     922          _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
     923          { return _M_refcount < __rhs._M_refcount; }
     924  
     925        template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
     926        template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
     927        friend class __enable_shared_from_this<_Tp, _Lp>;
     928        friend class enable_shared_from_this<_Tp>;
     929  
     930        // Friend injected into namespace and found by ADL.
     931        template<typename _Tp1>
     932          friend inline bool
     933          operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
     934          { return __lhs._M_less(__rhs); }
     935  
     936        _Tp*       	 _M_ptr;         // Contained pointer.
     937        __weak_count<_Lp>  _M_refcount;    // Reference counter.
     938      };
     939  
     940    // 2.2.4.7 weak_ptr specialized algorithms.
     941    template<typename _Tp, _Lock_policy _Lp>
     942      inline void
     943      swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
     944      { __a.swap(__b); }
     945  
     946  
     947    template<typename _Tp, _Lock_policy _Lp>
     948      class __enable_shared_from_this
     949      {
     950      protected:
     951        __enable_shared_from_this() { }
     952        
     953        __enable_shared_from_this(const __enable_shared_from_this&) { }
     954        
     955        __enable_shared_from_this&
     956        operator=(const __enable_shared_from_this&)
     957        { return *this; }
     958  
     959        ~__enable_shared_from_this() { }
     960        
     961      public:
     962        __shared_ptr<_Tp, _Lp>
     963        shared_from_this()
     964        { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
     965  
     966        __shared_ptr<const _Tp, _Lp>
     967        shared_from_this() const
     968        { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
     969  
     970      private:
     971        template<typename _Tp1>
     972          void
     973          _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
     974          { _M_weak_this._M_assign(__p, __n); }
     975  
     976        template<typename _Tp1>
     977          friend void
     978          __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
     979  					 const __enable_shared_from_this* __pe,
     980  					 const _Tp1* __px)
     981          {
     982  	  if (__pe != 0)
     983  	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
     984  	}
     985  
     986        mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
     987      };
     988  
     989  
     990    // The actual shared_ptr, with forwarding constructors and
     991    // assignment operators.
     992    template<typename _Tp>
     993      class shared_ptr
     994      : public __shared_ptr<_Tp>
     995      {
     996      public:
     997        shared_ptr()
     998        : __shared_ptr<_Tp>() { }
     999  
    1000        template<typename _Tp1>
    1001          explicit
    1002          shared_ptr(_Tp1* __p)
    1003  	: __shared_ptr<_Tp>(__p) { }
    1004  
    1005        template<typename _Tp1, typename _Deleter>
    1006          shared_ptr(_Tp1* __p, _Deleter __d)
    1007  	: __shared_ptr<_Tp>(__p, __d) { }
    1008  
    1009        template<typename _Tp1>
    1010          shared_ptr(const shared_ptr<_Tp1>& __r)
    1011  	: __shared_ptr<_Tp>(__r) { }
    1012  
    1013        template<typename _Tp1>
    1014          explicit
    1015          shared_ptr(const weak_ptr<_Tp1>& __r)
    1016  	: __shared_ptr<_Tp>(__r) { }
    1017  
    1018  #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
    1019  #pragma GCC diagnostic push
    1020  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    1021        template<typename _Tp1>
    1022          explicit
    1023          shared_ptr(std::auto_ptr<_Tp1>& __r)
    1024  	: __shared_ptr<_Tp>(__r) { }
    1025  #pragma GCC diagnostic pop
    1026  #endif
    1027  
    1028        template<typename _Tp1>
    1029          shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
    1030  	: __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
    1031  
    1032        template<typename _Tp1>
    1033          shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
    1034  	: __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
    1035  
    1036        template<typename _Tp1>
    1037          shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
    1038  	: __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
    1039  
    1040        template<typename _Tp1>
    1041          shared_ptr&
    1042          operator=(const shared_ptr<_Tp1>& __r) // never throws
    1043          {
    1044  	  this->__shared_ptr<_Tp>::operator=(__r);
    1045  	  return *this;
    1046  	}
    1047  
    1048  #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
    1049  #pragma GCC diagnostic push
    1050  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    1051        template<typename _Tp1>
    1052          shared_ptr&
    1053          operator=(std::auto_ptr<_Tp1>& __r)
    1054          {
    1055  	  this->__shared_ptr<_Tp>::operator=(__r);
    1056  	  return *this;
    1057  	}
    1058  #pragma GCC diagnostic pop
    1059  #endif
    1060      };
    1061  
    1062    // 2.2.3.8 shared_ptr specialized algorithms.
    1063    template<typename _Tp>
    1064      inline void
    1065      swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b)
    1066      { __a.swap(__b); }
    1067  
    1068    template<typename _Tp, typename _Tp1>
    1069      inline shared_ptr<_Tp>
    1070      static_pointer_cast(const shared_ptr<_Tp1>& __r)
    1071      { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
    1072  
    1073    template<typename _Tp, typename _Tp1>
    1074      inline shared_ptr<_Tp>
    1075      const_pointer_cast(const shared_ptr<_Tp1>& __r)
    1076      { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
    1077  
    1078    template<typename _Tp, typename _Tp1>
    1079      inline shared_ptr<_Tp>
    1080      dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
    1081      { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
    1082  
    1083  
    1084    // The actual weak_ptr, with forwarding constructors and
    1085    // assignment operators.
    1086    template<typename _Tp>
    1087      class weak_ptr
    1088      : public __weak_ptr<_Tp>
    1089      {
    1090      public:
    1091        weak_ptr()
    1092        : __weak_ptr<_Tp>() { }
    1093        
    1094        template<typename _Tp1>
    1095          weak_ptr(const weak_ptr<_Tp1>& __r)
    1096  	: __weak_ptr<_Tp>(__r) { }
    1097  
    1098        template<typename _Tp1>
    1099          weak_ptr(const shared_ptr<_Tp1>& __r)
    1100  	: __weak_ptr<_Tp>(__r) { }
    1101  
    1102        template<typename _Tp1>
    1103          weak_ptr&
    1104          operator=(const weak_ptr<_Tp1>& __r) // never throws
    1105          {
    1106  	  this->__weak_ptr<_Tp>::operator=(__r);
    1107  	  return *this;
    1108  	}
    1109  
    1110        template<typename _Tp1>
    1111          weak_ptr&
    1112          operator=(const shared_ptr<_Tp1>& __r) // never throws
    1113          {
    1114  	  this->__weak_ptr<_Tp>::operator=(__r);
    1115  	  return *this;
    1116  	}
    1117  
    1118        shared_ptr<_Tp>
    1119        lock() const // never throws
    1120        {
    1121  #ifdef __GTHREADS
    1122  	if (this->expired())
    1123  	  return shared_ptr<_Tp>();
    1124  
    1125  	__try
    1126  	  {
    1127  	    return shared_ptr<_Tp>(*this);
    1128  	  }
    1129  	__catch(const bad_weak_ptr&)
    1130  	  {
    1131  	    return shared_ptr<_Tp>();
    1132  	  }
    1133  #else
    1134  	return this->expired() ? shared_ptr<_Tp>()
    1135  	                       : shared_ptr<_Tp>(*this);
    1136  #endif
    1137        }
    1138      };
    1139  
    1140    template<typename _Tp>
    1141      class enable_shared_from_this
    1142      {
    1143      protected:
    1144        enable_shared_from_this() { }
    1145        
    1146        enable_shared_from_this(const enable_shared_from_this&) { }
    1147  
    1148        enable_shared_from_this&
    1149        operator=(const enable_shared_from_this&)
    1150        { return *this; }
    1151  
    1152        ~enable_shared_from_this() { }
    1153  
    1154      public:
    1155        shared_ptr<_Tp>
    1156        shared_from_this()
    1157        { return shared_ptr<_Tp>(this->_M_weak_this); }
    1158  
    1159        shared_ptr<const _Tp>
    1160        shared_from_this() const
    1161        { return shared_ptr<const _Tp>(this->_M_weak_this); }
    1162  
    1163      private:
    1164        template<typename _Tp1>
    1165          void
    1166          _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
    1167          { _M_weak_this._M_assign(__p, __n); }
    1168  
    1169        template<typename _Tp1>
    1170          friend void
    1171          __enable_shared_from_this_helper(const __shared_count<>& __pn,
    1172  					 const enable_shared_from_this* __pe,
    1173  					 const _Tp1* __px)
    1174          {
    1175  	  if (__pe != 0)
    1176  	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
    1177  	}
    1178  
    1179        mutable weak_ptr<_Tp>  _M_weak_this;
    1180      };
    1181  }
    1182  
    1183  _GLIBCXX_END_NAMESPACE_VERSION
    1184  }
    1185  
    1186  #endif // _TR1_SHARED_PTR_H