LCOV - code coverage report
Current view: top level - usr/include/c++/6/bits - shared_ptr_base.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 200 229 87.3 %
Date: 2018-11-15 08:49:49 Functions: 287 407 70.5 %

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

Generated by: LCOV version 1.13