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