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