wpkg test coverage results

Coverage test results of the Windows Packager by Made to Order Software Corporation.

LCOV - code coverage report
Current view: top level - usr/include/c++/4.6/bits - shared_ptr_base.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 3 0.0 %
Date: 2013-06-17 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.9

The wpkg tool is an open source tool created by Made to Order Software Corporation.