LCOV - code coverage report
Current view: top level - usr/include/c++/4.8/bits - shared_ptr_base.h (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 162 173 93.6 %
Date: 2015-10-10 Functions: 220 241 91.3 %

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

Generated by: LCOV version 1.10