LCOV - code coverage report
Current view: top level - usr/include/c++/4.4/tr1 - shared_ptr.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 26 58 44.8 %
Date: 2017-07-14 10:03:36 Functions: 12 136 8.8 %

          Line data    Source code
       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           0 :     {
      65             :     public:
      66             :       /**
      67             :        *  @brief   
      68             :        *  @pre     __d(__p) must not throw.
      69             :        */
      70      142524 :       _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
      71      142524 :       : _M_ptr(__p), _M_del(__d) { }
      72             :     
      73             :       virtual void
      74           0 :       _M_dispose() // nothrow
      75           0 :       { _M_del(_M_ptr); }
      76             :       
      77             :       virtual void*
      78           0 :       _M_get_deleter(const std::type_info& __ti)
      79           0 :       { 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           0 :       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           0 :       __shared_count()
     105           0 :       : _M_pi(0) // nothrow
     106           0 :       { }
     107             :   
     108             :       template<typename _Ptr>
     109      142524 :         __shared_count(_Ptr __p) : _M_pi(0)
     110             :         {
     111             :           __try
     112             :             {
     113             :               typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
     114      142524 :               _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
     115             :                   __p, _Sp_deleter<_Tp>());
     116             :             }
     117           0 :           __catch(...)
     118             :             {
     119           0 :               delete __p;
     120           0 :               __throw_exception_again;
     121             :             }
     122      142524 :         }
     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      142524 :       ~__shared_count() // nothrow
     151             :       {
     152      142524 :         if (_M_pi != 0)
     153      142524 :           _M_pi->_M_release();
     154      142524 :       }
     155             :       
     156      142524 :       __shared_count(const __shared_count& __r)
     157      142524 :       : _M_pi(__r._M_pi) // nothrow
     158             :       {
     159      142524 :         if (_M_pi != 0)
     160      142524 :           _M_pi->_M_add_ref_copy();
     161      142524 :       }
     162             :   
     163             :       __shared_count&
     164           0 :       operator=(const __shared_count& __r) // nothrow
     165             :       {
     166           0 :         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
     167           0 :         if (__tmp != _M_pi)
     168             :           {
     169           0 :             if (__tmp != 0)
     170           0 :               __tmp->_M_add_ref_copy();
     171           0 :             if (_M_pi != 0)
     172           0 :               _M_pi->_M_release();
     173           0 :             _M_pi = __tmp;
     174             :           }
     175           0 :         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      142524 :     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
     342      142524 :     { }
     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      285048 :     {
     359             :     public:
     360             :       typedef _Tp   element_type;
     361             :       
     362             :       /** @brief  Construct an empty %__shared_ptr.
     363             :        *  @post   use_count()==0 && get()==0
     364             :        */
     365           0 :       __shared_ptr()
     366           0 :       : _M_ptr(0), _M_refcount() // never throws
     367           0 :       { }
     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      142524 :         __shared_ptr(_Tp1* __p)
     377      142524 :         : _M_ptr(__p), _M_refcount(__p)
     378             :         {
     379             :           __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
     380             :           // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
     381      142524 :           __enable_shared_from_this_helper(_M_refcount, __p, __p);
     382      142524 :         }
     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           0 :       operator*() const // never throws
     516             :       {
     517             :         _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
     518           0 :         return *_M_ptr;
     519             :       }
     520             : 
     521             :       _Tp*
     522     6183013 :       operator->() const // never throws
     523             :       {
     524             :         _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
     525     6183013 :         return _M_ptr;
     526             :       }
     527             :     
     528             :       _Tp*
     529           0 :       get() const // never throws
     530           0 :       { return _M_ptr; }
     531             : 
     532             :       // Implicit conversion to "bool"
     533             :     private:
     534             :       typedef _Tp* __shared_ptr::*__unspecified_bool_type;
     535             : 
     536             :     public:
     537           0 :       operator __unspecified_bool_type() const // never throws
     538           0 :       { 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      285048 :     {
     835             :     public:
     836           0 :       shared_ptr()
     837           0 :       : __shared_ptr<_Tp>() { }
     838             : 
     839             :       template<typename _Tp1>
     840             :         explicit
     841      142524 :         shared_ptr(_Tp1* __p)
     842      142524 :         : __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

Generated by: LCOV version 1.11