Home | History | Annotate | Download | only in tr1
      1 // <tr1/shared_ptr.h> -*- C++ -*-
      2 
      3 // Copyright (C) 2007, 2008, 2009 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  *  You should not attempt to use it directly.
     47  */
     48 
     49 #ifndef _TR1_SHARED_PTR_H
     50 #define _TR1_SHARED_PTR_H 1
     51 
     52 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
     53 #  error TR1 header cannot be included from C++0x header
     54 #endif
     55 
     56 namespace std
     57 {
     58 namespace tr1
     59 {
     60 
     61   template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
     62     class _Sp_counted_base_impl
     63     : public _Sp_counted_base<_Lp>
     64     {
     65     public:
     66       /**
     67        *  @brief
     68        *  @pre     __d(__p) must not throw.
     69        */
     70       _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
     71       : _M_ptr(__p), _M_del(__d) { }
     72 
     73       virtual void
     74       _M_dispose() // nothrow
     75       { _M_del(_M_ptr); }
     76 
     77       virtual void*
     78       _M_get_deleter(const std::type_info& __ti)
     79       { return __ti == typeid(_Deleter) ? &_M_del : 0; }
     80 
     81     private:
     82       _Sp_counted_base_impl(const _Sp_counted_base_impl&);
     83       _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
     84 
     85       _Ptr      _M_ptr;  // copy constructor must not throw
     86       _Deleter  _M_del;  // copy constructor must not throw
     87     };
     88 
     89   template<_Lock_policy _Lp = __default_lock_policy>
     90     class __weak_count;
     91 
     92   template<typename _Tp>
     93     struct _Sp_deleter
     94     {
     95       typedef void result_type;
     96       typedef _Tp* argument_type;
     97       void operator()(_Tp* __p) const { delete __p; }
     98     };
     99 
    100   template<_Lock_policy _Lp = __default_lock_policy>
    101     class __shared_count
    102     {
    103     public:
    104       __shared_count()
    105       : _M_pi(0) // nothrow
    106       { }
    107 
    108       template<typename _Ptr>
    109         __shared_count(_Ptr __p) : _M_pi(0)
    110         {
    111 	  __try
    112 	    {
    113 	      typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
    114 	      _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
    115 	          __p, _Sp_deleter<_Tp>());
    116 	    }
    117 	  __catch(...)
    118 	    {
    119 	      delete __p;
    120 	      __throw_exception_again;
    121 	    }
    122 	}
    123 
    124       template<typename _Ptr, typename _Deleter>
    125         __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
    126         {
    127 	  __try
    128 	    {
    129 	      _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
    130 	    }
    131 	  __catch(...)
    132 	    {
    133 	      __d(__p); // Call _Deleter on __p.
    134 	      __throw_exception_again;
    135 	    }
    136 	}
    137 
    138       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
    139       template<typename _Tp>
    140         explicit
    141         __shared_count(std::auto_ptr<_Tp>& __r)
    142 	: _M_pi(new _Sp_counted_base_impl<_Tp*,
    143 		_Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
    144         { __r.release(); }
    145 
    146       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
    147       explicit
    148       __shared_count(const __weak_count<_Lp>& __r);
    149 
    150       ~__shared_count() // nothrow
    151       {
    152 	if (_M_pi != 0)
    153 	  _M_pi->_M_release();
    154       }
    155 
    156       __shared_count(const __shared_count& __r)
    157       : _M_pi(__r._M_pi) // nothrow
    158       {
    159 	if (_M_pi != 0)
    160 	  _M_pi->_M_add_ref_copy();
    161       }
    162 
    163       __shared_count&
    164       operator=(const __shared_count& __r) // nothrow
    165       {
    166 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    167 	if (__tmp != _M_pi)
    168 	  {
    169 	    if (__tmp != 0)
    170 	      __tmp->_M_add_ref_copy();
    171 	    if (_M_pi != 0)
    172 	      _M_pi->_M_release();
    173 	    _M_pi = __tmp;
    174 	  }
    175 	return *this;
    176       }
    177 
    178       void
    179       _M_swap(__shared_count& __r) // nothrow
    180       {
    181 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    182 	__r._M_pi = _M_pi;
    183 	_M_pi = __tmp;
    184       }
    185 
    186       long
    187       _M_get_use_count() const // nothrow
    188       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
    189 
    190       bool
    191       _M_unique() const // nothrow
    192       { return this->_M_get_use_count() == 1; }
    193 
    194       friend inline bool
    195       operator==(const __shared_count& __a, const __shared_count& __b)
    196       { return __a._M_pi == __b._M_pi; }
    197 
    198       friend inline bool
    199       operator<(const __shared_count& __a, const __shared_count& __b)
    200       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
    201 
    202       void*
    203       _M_get_deleter(const std::type_info& __ti) const
    204       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
    205 
    206     private:
    207       friend class __weak_count<_Lp>;
    208 
    209       _Sp_counted_base<_Lp>*  _M_pi;
    210     };
    211 
    212 
    213   template<_Lock_policy _Lp>
    214     class __weak_count
    215     {
    216     public:
    217       __weak_count()
    218       : _M_pi(0) // nothrow
    219       { }
    220 
    221       __weak_count(const __shared_count<_Lp>& __r)
    222       : _M_pi(__r._M_pi) // nothrow
    223       {
    224 	if (_M_pi != 0)
    225 	  _M_pi->_M_weak_add_ref();
    226       }
    227 
    228       __weak_count(const __weak_count<_Lp>& __r)
    229       : _M_pi(__r._M_pi) // nothrow
    230       {
    231 	if (_M_pi != 0)
    232 	  _M_pi->_M_weak_add_ref();
    233       }
    234 
    235       ~__weak_count() // nothrow
    236       {
    237 	if (_M_pi != 0)
    238 	  _M_pi->_M_weak_release();
    239       }
    240 
    241       __weak_count<_Lp>&
    242       operator=(const __shared_count<_Lp>& __r) // nothrow
    243       {
    244 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    245 	if (__tmp != 0)
    246 	  __tmp->_M_weak_add_ref();
    247 	if (_M_pi != 0)
    248 	  _M_pi->_M_weak_release();
    249 	_M_pi = __tmp;
    250 	return *this;
    251       }
    252 
    253       __weak_count<_Lp>&
    254       operator=(const __weak_count<_Lp>& __r) // nothrow
    255       {
    256 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    257 	if (__tmp != 0)
    258 	  __tmp->_M_weak_add_ref();
    259 	if (_M_pi != 0)
    260 	  _M_pi->_M_weak_release();
    261 	_M_pi = __tmp;
    262 	return *this;
    263       }
    264 
    265       void
    266       _M_swap(__weak_count<_Lp>& __r) // nothrow
    267       {
    268 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    269 	__r._M_pi = _M_pi;
    270 	_M_pi = __tmp;
    271       }
    272 
    273       long
    274       _M_get_use_count() const // nothrow
    275       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
    276 
    277       friend inline bool
    278       operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
    279       { return __a._M_pi == __b._M_pi; }
    280 
    281       friend inline bool
    282       operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
    283       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
    284 
    285     private:
    286       friend class __shared_count<_Lp>;
    287 
    288       _Sp_counted_base<_Lp>*  _M_pi;
    289     };
    290 
    291   // now that __weak_count is defined we can define this constructor:
    292   template<_Lock_policy _Lp>
    293     inline
    294     __shared_count<_Lp>::
    295     __shared_count(const __weak_count<_Lp>& __r)
    296     : _M_pi(__r._M_pi)
    297     {
    298       if (_M_pi != 0)
    299 	_M_pi->_M_add_ref_lock();
    300       else
    301 	__throw_bad_weak_ptr();
    302     }
    303 
    304   // Forward declarations.
    305   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    306     class __shared_ptr;
    307 
    308   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    309     class __weak_ptr;
    310 
    311   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    312     class __enable_shared_from_this;
    313 
    314   template<typename _Tp>
    315     class shared_ptr;
    316 
    317   template<typename _Tp>
    318     class weak_ptr;
    319 
    320   template<typename _Tp>
    321     class enable_shared_from_this;
    322 
    323   // Support for enable_shared_from_this.
    324 
    325   // Friend of __enable_shared_from_this.
    326   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
    327     void
    328     __enable_shared_from_this_helper(const __shared_count<_Lp>&,
    329 				     const __enable_shared_from_this<_Tp1,
    330 				     _Lp>*, const _Tp2*);
    331 
    332   // Friend of enable_shared_from_this.
    333   template<typename _Tp1, typename _Tp2>
    334     void
    335     __enable_shared_from_this_helper(const __shared_count<>&,
    336 				     const enable_shared_from_this<_Tp1>*,
    337 				     const _Tp2*);
    338 
    339   template<_Lock_policy _Lp>
    340     inline void
    341     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
    342     { }
    343 
    344 
    345   struct __static_cast_tag { };
    346   struct __const_cast_tag { };
    347   struct __dynamic_cast_tag { };
    348 
    349   /**
    350    *  @class __shared_ptr
    351    *
    352    *  A smart pointer with reference-counted copy semantics.
    353    *  The object pointed to is deleted when the last shared_ptr pointing to
    354    *  it is destroyed or reset.
    355    */
    356   template<typename _Tp, _Lock_policy _Lp>
    357     class __shared_ptr
    358     {
    359     public:
    360       typedef _Tp   element_type;
    361 
    362       /** @brief  Construct an empty %__shared_ptr.
    363        *  @post   use_count()==0 && get()==0
    364        */
    365       __shared_ptr()
    366       : _M_ptr(0), _M_refcount() // never throws
    367       { }
    368 
    369       /** @brief  Construct a %__shared_ptr that owns the pointer @a __p.
    370        *  @param  __p  A pointer that is convertible to element_type*.
    371        *  @post   use_count() == 1 && get() == __p
    372        *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
    373        */
    374       template<typename _Tp1>
    375         explicit
    376         __shared_ptr(_Tp1* __p)
    377 	: _M_ptr(__p), _M_refcount(__p)
    378         {
    379 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    380 	  // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
    381 	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
    382 	}
    383 
    384       //
    385       // Requirements: _Deleter's copy constructor and destructor must
    386       // not throw
    387       //
    388       // __shared_ptr will release __p by calling __d(__p)
    389       //
    390       /** @brief  Construct a %__shared_ptr that owns the pointer @a __p
    391        *          and the deleter @a __d.
    392        *  @param  __p  A pointer.
    393        *  @param  __d  A deleter.
    394        *  @post   use_count() == 1 && get() == __p
    395        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
    396        */
    397       template<typename _Tp1, typename _Deleter>
    398         __shared_ptr(_Tp1* __p, _Deleter __d)
    399         : _M_ptr(__p), _M_refcount(__p, __d)
    400         {
    401 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    402 	  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
    403 	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
    404 	}
    405 
    406       //  generated copy constructor, assignment, destructor are fine.
    407 
    408       /** @brief  If @a __r is empty, constructs an empty %__shared_ptr;
    409        *          otherwise construct a %__shared_ptr that shares ownership
    410        *          with @a __r.
    411        *  @param  __r  A %__shared_ptr.
    412        *  @post   get() == __r.get() && use_count() == __r.use_count()
    413        */
    414       template<typename _Tp1>
    415         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
    416 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    417         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
    418 
    419       /** @brief  Constructs a %__shared_ptr that shares ownership with @a __r
    420        *          and stores a copy of the pointer stored in @a __r.
    421        *  @param  __r  A weak_ptr.
    422        *  @post   use_count() == __r.use_count()
    423        *  @throw  bad_weak_ptr when __r.expired(),
    424        *          in which case the constructor has no effect.
    425        */
    426       template<typename _Tp1>
    427         explicit
    428         __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    429 	: _M_refcount(__r._M_refcount) // may throw
    430         {
    431 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    432 	  // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
    433 	  // did not throw.
    434 	  _M_ptr = __r._M_ptr;
    435 	}
    436 
    437 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
    438       /**
    439        * @post use_count() == 1 and __r.get() == 0
    440        */
    441       template<typename _Tp1>
    442         explicit
    443         __shared_ptr(std::auto_ptr<_Tp1>& __r)
    444 	: _M_ptr(__r.get()), _M_refcount()
    445         {
    446 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    447 	  // TODO requires _Tp1 is complete, delete __r.release() well-formed
    448 	  _Tp1* __tmp = __r.get();
    449 	  _M_refcount = __shared_count<_Lp>(__r);
    450 	  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
    451 	}
    452 
    453 #endif
    454 
    455       template<typename _Tp1>
    456         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
    457 	: _M_ptr(static_cast<element_type*>(__r._M_ptr)),
    458 	  _M_refcount(__r._M_refcount)
    459         { }
    460 
    461       template<typename _Tp1>
    462         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
    463 	: _M_ptr(const_cast<element_type*>(__r._M_ptr)),
    464 	  _M_refcount(__r._M_refcount)
    465         { }
    466 
    467       template<typename _Tp1>
    468         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
    469 	: _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
    470 	  _M_refcount(__r._M_refcount)
    471         {
    472 	  if (_M_ptr == 0) // need to allocate new counter -- the cast failed
    473 	    _M_refcount = __shared_count<_Lp>();
    474 	}
    475 
    476       template<typename _Tp1>
    477         __shared_ptr&
    478         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
    479         {
    480 	  _M_ptr = __r._M_ptr;
    481 	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
    482 	  return *this;
    483 	}
    484 
    485 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
    486       template<typename _Tp1>
    487         __shared_ptr&
    488         operator=(std::auto_ptr<_Tp1>& __r)
    489         {
    490 	  __shared_ptr(__r).swap(*this);
    491 	  return *this;
    492 	}
    493 #endif
    494 
    495       void
    496       reset() // never throws
    497       { __shared_ptr().swap(*this); }
    498 
    499       template<typename _Tp1>
    500         void
    501         reset(_Tp1* __p) // _Tp1 must be complete.
    502         {
    503 	  // Catch self-reset errors.
    504 	  _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
    505 	  __shared_ptr(__p).swap(*this);
    506 	}
    507 
    508       template<typename _Tp1, typename _Deleter>
    509         void
    510         reset(_Tp1* __p, _Deleter __d)
    511         { __shared_ptr(__p, __d).swap(*this); }
    512 
    513       // Allow class instantiation when _Tp is [cv-qual] void.
    514       typename std::tr1::add_reference<_Tp>::type
    515       operator*() const // never throws
    516       {
    517 	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    518 	return *_M_ptr;
    519       }
    520 
    521       _Tp*
    522       operator->() const // never throws
    523       {
    524 	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    525 	return _M_ptr;
    526       }
    527 
    528       _Tp*
    529       get() const // never throws
    530       { return _M_ptr; }
    531 
    532       // Implicit conversion to "bool"
    533     private:
    534       typedef _Tp* __shared_ptr::*__unspecified_bool_type;
    535 
    536     public:
    537       operator __unspecified_bool_type() const // never throws
    538       { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
    539 
    540       bool
    541       unique() const // never throws
    542       { return _M_refcount._M_unique(); }
    543 
    544       long
    545       use_count() const // never throws
    546       { return _M_refcount._M_get_use_count(); }
    547 
    548       void
    549       swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
    550       {
    551 	std::swap(_M_ptr, __other._M_ptr);
    552 	_M_refcount._M_swap(__other._M_refcount);
    553       }
    554 
    555     private:
    556       void*
    557       _M_get_deleter(const std::type_info& __ti) const
    558       { return _M_refcount._M_get_deleter(__ti); }
    559 
    560       template<typename _Tp1, _Lock_policy _Lp1>
    561         bool
    562         _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
    563         { return _M_refcount < __rhs._M_refcount; }
    564 
    565       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
    566       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
    567 
    568       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
    569         friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
    570 
    571       // Friends injected into enclosing namespace and found by ADL:
    572       template<typename _Tp1>
    573         friend inline bool
    574         operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    575         { return __a.get() == __b.get(); }
    576 
    577       template<typename _Tp1>
    578         friend inline bool
    579         operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    580         { return __a.get() != __b.get(); }
    581 
    582       template<typename _Tp1>
    583         friend inline bool
    584         operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    585         { return __a._M_less(__b); }
    586 
    587       _Tp*         	   _M_ptr;         // Contained pointer.
    588       __shared_count<_Lp>  _M_refcount;    // Reference counter.
    589     };
    590 
    591   // 2.2.3.8 shared_ptr specialized algorithms.
    592   template<typename _Tp, _Lock_policy _Lp>
    593     inline void
    594     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
    595     { __a.swap(__b); }
    596 
    597   // 2.2.3.9 shared_ptr casts
    598   /** @warning The seemingly equivalent
    599    *           <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
    600    *           will eventually result in undefined behaviour,
    601    *           attempting to delete the same object twice.
    602    */
    603   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    604     inline __shared_ptr<_Tp, _Lp>
    605     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    606     { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
    607 
    608   /** @warning The seemingly equivalent
    609    *           <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
    610    *           will eventually result in undefined behaviour,
    611    *           attempting to delete the same object twice.
    612    */
    613   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    614     inline __shared_ptr<_Tp, _Lp>
    615     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    616     { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
    617 
    618   /** @warning The seemingly equivalent
    619    *           <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
    620    *           will eventually result in undefined behaviour,
    621    *           attempting to delete the same object twice.
    622    */
    623   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    624     inline __shared_ptr<_Tp, _Lp>
    625     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    626     { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
    627 
    628   // 2.2.3.7 shared_ptr I/O
    629   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
    630     std::basic_ostream<_Ch, _Tr>&
    631     operator<<(std::basic_ostream<_Ch, _Tr>& __os,
    632 	       const __shared_ptr<_Tp, _Lp>& __p)
    633     {
    634       __os << __p.get();
    635       return __os;
    636     }
    637 
    638   // 2.2.3.10 shared_ptr get_deleter (experimental)
    639   template<typename _Del, typename _Tp, _Lock_policy _Lp>
    640     inline _Del*
    641     get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
    642     { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
    643 
    644 
    645   template<typename _Tp, _Lock_policy _Lp>
    646     class __weak_ptr
    647     {
    648     public:
    649       typedef _Tp element_type;
    650 
    651       __weak_ptr()
    652       : _M_ptr(0), _M_refcount() // never throws
    653       { }
    654 
    655       // Generated copy constructor, assignment, destructor are fine.
    656 
    657       // The "obvious" converting constructor implementation:
    658       //
    659       //  template<typename _Tp1>
    660       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    661       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    662       //    { }
    663       //
    664       // has a serious problem.
    665       //
    666       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
    667       //  conversion may require access to *__r._M_ptr (virtual inheritance).
    668       //
    669       // It is not possible to avoid spurious access violations since
    670       // in multithreaded programs __r._M_ptr may be invalidated at any point.
    671       template<typename _Tp1>
    672         __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    673 	: _M_refcount(__r._M_refcount) // never throws
    674         {
    675 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    676 	  _M_ptr = __r.lock().get();
    677 	}
    678 
    679       template<typename _Tp1>
    680         __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
    681 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    682         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
    683 
    684       template<typename _Tp1>
    685         __weak_ptr&
    686         operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
    687         {
    688 	  _M_ptr = __r.lock().get();
    689 	  _M_refcount = __r._M_refcount;
    690 	  return *this;
    691 	}
    692 
    693       template<typename _Tp1>
    694         __weak_ptr&
    695         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
    696         {
    697 	  _M_ptr = __r._M_ptr;
    698 	  _M_refcount = __r._M_refcount;
    699 	  return *this;
    700 	}
    701 
    702       __shared_ptr<_Tp, _Lp>
    703       lock() const // never throws
    704       {
    705 #ifdef __GTHREADS
    706 	// Optimization: avoid throw overhead.
    707 	if (expired())
    708 	  return __shared_ptr<element_type, _Lp>();
    709 
    710 	__try
    711 	  {
    712 	    return __shared_ptr<element_type, _Lp>(*this);
    713 	  }
    714 	__catch(const bad_weak_ptr&)
    715 	  {
    716 	    // Q: How can we get here?
    717 	    // A: Another thread may have invalidated r after the
    718 	    //    use_count test above.
    719 	    return __shared_ptr<element_type, _Lp>();
    720 	  }
    721 
    722 #else
    723 	// Optimization: avoid try/catch overhead when single threaded.
    724 	return expired() ? __shared_ptr<element_type, _Lp>()
    725 	                 : __shared_ptr<element_type, _Lp>(*this);
    726 
    727 #endif
    728       } // XXX MT
    729 
    730       long
    731       use_count() const // never throws
    732       { return _M_refcount._M_get_use_count(); }
    733 
    734       bool
    735       expired() const // never throws
    736       { return _M_refcount._M_get_use_count() == 0; }
    737 
    738       void
    739       reset() // never throws
    740       { __weak_ptr().swap(*this); }
    741 
    742       void
    743       swap(__weak_ptr& __s) // never throws
    744       {
    745 	std::swap(_M_ptr, __s._M_ptr);
    746 	_M_refcount._M_swap(__s._M_refcount);
    747       }
    748 
    749     private:
    750       // Used by __enable_shared_from_this.
    751       void
    752       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
    753       {
    754 	_M_ptr = __ptr;
    755 	_M_refcount = __refcount;
    756       }
    757 
    758       template<typename _Tp1>
    759         bool
    760         _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
    761         { return _M_refcount < __rhs._M_refcount; }
    762 
    763       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
    764       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
    765       friend class __enable_shared_from_this<_Tp, _Lp>;
    766       friend class enable_shared_from_this<_Tp>;
    767 
    768       // Friend injected into namespace and found by ADL.
    769       template<typename _Tp1>
    770         friend inline bool
    771         operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
    772         { return __lhs._M_less(__rhs); }
    773 
    774       _Tp*       	 _M_ptr;         // Contained pointer.
    775       __weak_count<_Lp>  _M_refcount;    // Reference counter.
    776     };
    777 
    778   // 2.2.4.7 weak_ptr specialized algorithms.
    779   template<typename _Tp, _Lock_policy _Lp>
    780     inline void
    781     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
    782     { __a.swap(__b); }
    783 
    784 
    785   template<typename _Tp, _Lock_policy _Lp>
    786     class __enable_shared_from_this
    787     {
    788     protected:
    789       __enable_shared_from_this() { }
    790 
    791       __enable_shared_from_this(const __enable_shared_from_this&) { }
    792 
    793       __enable_shared_from_this&
    794       operator=(const __enable_shared_from_this&)
    795       { return *this; }
    796 
    797       ~__enable_shared_from_this() { }
    798 
    799     public:
    800       __shared_ptr<_Tp, _Lp>
    801       shared_from_this()
    802       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
    803 
    804       __shared_ptr<const _Tp, _Lp>
    805       shared_from_this() const
    806       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
    807 
    808     private:
    809       template<typename _Tp1>
    810         void
    811         _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
    812         { _M_weak_this._M_assign(__p, __n); }
    813 
    814       template<typename _Tp1>
    815         friend void
    816         __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
    817 					 const __enable_shared_from_this* __pe,
    818 					 const _Tp1* __px)
    819         {
    820 	  if (__pe != 0)
    821 	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
    822 	}
    823 
    824       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
    825     };
    826 
    827 
    828   /// shared_ptr
    829   // The actual shared_ptr, with forwarding constructors and
    830   // assignment operators.
    831   template<typename _Tp>
    832     class shared_ptr
    833     : public __shared_ptr<_Tp>
    834     {
    835     public:
    836       shared_ptr()
    837       : __shared_ptr<_Tp>() { }
    838 
    839       template<typename _Tp1>
    840         explicit
    841         shared_ptr(_Tp1* __p)
    842 	: __shared_ptr<_Tp>(__p) { }
    843 
    844       template<typename _Tp1, typename _Deleter>
    845         shared_ptr(_Tp1* __p, _Deleter __d)
    846 	: __shared_ptr<_Tp>(__p, __d) { }
    847 
    848       template<typename _Tp1>
    849         shared_ptr(const shared_ptr<_Tp1>& __r)
    850 	: __shared_ptr<_Tp>(__r) { }
    851 
    852       template<typename _Tp1>
    853         explicit
    854         shared_ptr(const weak_ptr<_Tp1>& __r)
    855 	: __shared_ptr<_Tp>(__r) { }
    856 
    857 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
    858       template<typename _Tp1>
    859         explicit
    860         shared_ptr(std::auto_ptr<_Tp1>& __r)
    861 	: __shared_ptr<_Tp>(__r) { }
    862 #endif
    863 
    864       template<typename _Tp1>
    865         shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
    866 	: __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
    867 
    868       template<typename _Tp1>
    869         shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
    870 	: __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
    871 
    872       template<typename _Tp1>
    873         shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
    874 	: __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
    875 
    876       template<typename _Tp1>
    877         shared_ptr&
    878         operator=(const shared_ptr<_Tp1>& __r) // never throws
    879         {
    880 	  this->__shared_ptr<_Tp>::operator=(__r);
    881 	  return *this;
    882 	}
    883 
    884 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
    885       template<typename _Tp1>
    886         shared_ptr&
    887         operator=(std::auto_ptr<_Tp1>& __r)
    888         {
    889 	  this->__shared_ptr<_Tp>::operator=(__r);
    890 	  return *this;
    891 	}
    892 #endif
    893     };
    894 
    895   // 2.2.3.8 shared_ptr specialized algorithms.
    896   template<typename _Tp>
    897     inline void
    898     swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b)
    899     { __a.swap(__b); }
    900 
    901   template<typename _Tp, typename _Tp1>
    902     inline shared_ptr<_Tp>
    903     static_pointer_cast(const shared_ptr<_Tp1>& __r)
    904     { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
    905 
    906   template<typename _Tp, typename _Tp1>
    907     inline shared_ptr<_Tp>
    908     const_pointer_cast(const shared_ptr<_Tp1>& __r)
    909     { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
    910 
    911   template<typename _Tp, typename _Tp1>
    912     inline shared_ptr<_Tp>
    913     dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
    914     { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
    915 
    916 
    917   /// weak_ptr
    918   // The actual weak_ptr, with forwarding constructors and
    919   // assignment operators.
    920   template<typename _Tp>
    921     class weak_ptr
    922     : public __weak_ptr<_Tp>
    923     {
    924     public:
    925       weak_ptr()
    926       : __weak_ptr<_Tp>() { }
    927 
    928       template<typename _Tp1>
    929         weak_ptr(const weak_ptr<_Tp1>& __r)
    930 	: __weak_ptr<_Tp>(__r) { }
    931 
    932       template<typename _Tp1>
    933         weak_ptr(const shared_ptr<_Tp1>& __r)
    934 	: __weak_ptr<_Tp>(__r) { }
    935 
    936       template<typename _Tp1>
    937         weak_ptr&
    938         operator=(const weak_ptr<_Tp1>& __r) // never throws
    939         {
    940 	  this->__weak_ptr<_Tp>::operator=(__r);
    941 	  return *this;
    942 	}
    943 
    944       template<typename _Tp1>
    945         weak_ptr&
    946         operator=(const shared_ptr<_Tp1>& __r) // never throws
    947         {
    948 	  this->__weak_ptr<_Tp>::operator=(__r);
    949 	  return *this;
    950 	}
    951 
    952       shared_ptr<_Tp>
    953       lock() const // never throws
    954       {
    955 #ifdef __GTHREADS
    956 	if (this->expired())
    957 	  return shared_ptr<_Tp>();
    958 
    959 	__try
    960 	  {
    961 	    return shared_ptr<_Tp>(*this);
    962 	  }
    963 	__catch(const bad_weak_ptr&)
    964 	  {
    965 	    return shared_ptr<_Tp>();
    966 	  }
    967 #else
    968 	return this->expired() ? shared_ptr<_Tp>()
    969 	                       : shared_ptr<_Tp>(*this);
    970 #endif
    971       }
    972     };
    973 
    974   /// enable_shared_from_this
    975   template<typename _Tp>
    976     class enable_shared_from_this
    977     {
    978     protected:
    979       enable_shared_from_this() { }
    980 
    981       enable_shared_from_this(const enable_shared_from_this&) { }
    982 
    983       enable_shared_from_this&
    984       operator=(const enable_shared_from_this&)
    985       { return *this; }
    986 
    987       ~enable_shared_from_this() { }
    988 
    989     public:
    990       shared_ptr<_Tp>
    991       shared_from_this()
    992       { return shared_ptr<_Tp>(this->_M_weak_this); }
    993 
    994       shared_ptr<const _Tp>
    995       shared_from_this() const
    996       { return shared_ptr<const _Tp>(this->_M_weak_this); }
    997 
    998     private:
    999       template<typename _Tp1>
   1000         void
   1001         _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
   1002         { _M_weak_this._M_assign(__p, __n); }
   1003 
   1004       template<typename _Tp1>
   1005         friend void
   1006         __enable_shared_from_this_helper(const __shared_count<>& __pn,
   1007 					 const enable_shared_from_this* __pe,
   1008 					 const _Tp1* __px)
   1009         {
   1010 	  if (__pe != 0)
   1011 	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
   1012 	}
   1013 
   1014       mutable weak_ptr<_Tp>  _M_weak_this;
   1015     };
   1016 
   1017 }
   1018 }
   1019 
   1020 #endif // _TR1_SHARED_PTR_H
   1021