LCOV - code coverage report
Current view: top level - 11/bits - shared_ptr_base.h (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 284 335 84.8 %
Date: 2025-08-24 09:11:10 Functions: 3181 3994 79.6 %

          Line data    Source code
       1             : // shared_ptr and weak_ptr implementation details -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2007-2021 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 <bits/allocator.h>
      55             : #include <bits/exception_defines.h>
      56             : #include <bits/functional_hash.h>
      57             : #include <bits/refwrap.h>
      58             : #include <bits/stl_function.h>  // std::less
      59             : #include <bits/unique_ptr.h>
      60             : #include <ext/aligned_buffer.h>
      61             : #include <ext/atomicity.h>
      62             : #include <ext/concurrence.h>
      63             : #if __cplusplus > 201703L
      64             : # include <compare>
      65             : #endif
      66             : 
      67             : namespace std _GLIBCXX_VISIBILITY(default)
      68             : {
      69             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      70             : 
      71             : #if _GLIBCXX_USE_DEPRECATED
      72             : #pragma GCC diagnostic push
      73             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
      74             :   template<typename> class auto_ptr;
      75             : #pragma GCC diagnostic pop
      76             : #endif
      77             : 
      78             :  /**
      79             :    *  @brief  Exception possibly thrown by @c shared_ptr.
      80             :    *  @ingroup exceptions
      81             :    */
      82             :   class bad_weak_ptr : public std::exception
      83             :   {
      84             :   public:
      85             :     virtual char const* what() const noexcept;
      86             : 
      87             :     virtual ~bad_weak_ptr() noexcept;
      88             :   };
      89             : 
      90             :   // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
      91             :   inline void
      92           0 :   __throw_bad_weak_ptr()
      93           0 :   { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
      94             : 
      95             :   using __gnu_cxx::_Lock_policy;
      96             :   using __gnu_cxx::__default_lock_policy;
      97             :   using __gnu_cxx::_S_single;
      98             :   using __gnu_cxx::_S_mutex;
      99             :   using __gnu_cxx::_S_atomic;
     100             : 
     101             :   // Empty helper class except when the template argument is _S_mutex.
     102             :   template<_Lock_policy _Lp>
     103             :     class _Mutex_base
     104             :     {
     105             :     protected:
     106             :       // The atomic policy uses fully-fenced builtins, single doesn't care.
     107             :       enum { _S_need_barriers = 0 };
     108             :     };
     109             : 
     110             :   template<>
     111             :     class _Mutex_base<_S_mutex>
     112             :     : public __gnu_cxx::__mutex
     113             :     {
     114             :     protected:
     115             :       // This policy is used when atomic builtins are not available.
     116             :       // The replacement atomic operations might not have the necessary
     117             :       // memory barriers.
     118             :       enum { _S_need_barriers = 1 };
     119             :     };
     120             : 
     121             :   template<_Lock_policy _Lp = __default_lock_policy>
     122             :     class _Sp_counted_base
     123             :     : public _Mutex_base<_Lp>
     124             :     {
     125             :     public:
     126      149060 :       _Sp_counted_base() noexcept
     127      149060 :       : _M_use_count(1), _M_weak_count(1) { }
     128             : 
     129             :       virtual
     130     1192585 :       ~_Sp_counted_base() noexcept
     131     1192585 :       { }
     132             : 
     133             :       // Called when _M_use_count drops to zero, to release the resources
     134             :       // managed by *this.
     135             :       virtual void
     136             :       _M_dispose() noexcept = 0;
     137             : 
     138             :       // Called when _M_weak_count drops to zero.
     139             :       virtual void
     140           0 :       _M_destroy() noexcept
     141           0 :       { delete this; }
     142             : 
     143             :       virtual void*
     144             :       _M_get_deleter(const std::type_info&) noexcept = 0;
     145             : 
     146             :       void
     147     9105967 :       _M_add_ref_copy()
     148     9105967 :       { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
     149             : 
     150             :       void
     151             :       _M_add_ref_lock()
     152             :       {
     153             :         if (!_M_add_ref_lock_nothrow())
     154             :           __throw_bad_weak_ptr();
     155             :       }
     156             : 
     157             :       bool
     158             :       _M_add_ref_lock_nothrow() noexcept;
     159             : 
     160             :       void
     161    26129332 :       _M_release() noexcept
     162             :       {
     163             :         // Be race-detector-friendly.  For more info see bits/c++config.
     164             :         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
     165    52258664 :         if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
     166             :           {
     167             :             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
     168     3883172 :             _M_dispose();
     169             :             // There must be a memory barrier between dispose() and destroy()
     170             :             // to ensure that the effects of dispose() are observed in the
     171             :             // thread that runs destroy().
     172             :             // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
     173             :             if (_Mutex_base<_Lp>::_S_need_barriers)
     174             :               {
     175             :                 __atomic_thread_fence (__ATOMIC_ACQ_REL);
     176             :               }
     177             : 
     178             :             // Be race-detector-friendly.  For more info see bits/c++config.
     179             :             _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
     180     3883136 :             if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
     181     3883136 :                                                        -1) == 1)
     182             :               {
     183             :                 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
     184     2962951 :                 _M_destroy();
     185             :               }
     186             :           }
     187    26129368 :       }
     188             : 
     189             :       void
     190     5528062 :       _M_weak_add_ref() noexcept
     191     5528062 :       { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
     192             : 
     193             :       void
     194     5562638 :       _M_weak_release() noexcept
     195             :       {
     196             :         // Be race-detector-friendly. For more info see bits/c++config.
     197             :         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
     198    11125276 :         if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
     199             :           {
     200             :             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
     201             :             if (_Mutex_base<_Lp>::_S_need_barriers)
     202             :               {
     203             :                 // See _M_release(),
     204             :                 // destroy() must observe results of dispose()
     205             :                 __atomic_thread_fence (__ATOMIC_ACQ_REL);
     206             :               }
     207        8047 :             _M_destroy();
     208             :           }
     209     5562638 :       }
     210             : 
     211             :       long
     212      350063 :       _M_get_use_count() const noexcept
     213             :       {
     214             :         // No memory barrier is used here so there is no synchronization
     215             :         // with other threads.
     216      350063 :         return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
     217             :       }
     218             : 
     219             :     private:
     220             :       _Sp_counted_base(_Sp_counted_base const&) = delete;
     221             :       _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
     222             : 
     223             :       _Atomic_word  _M_use_count;     // #shared
     224             :       _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
     225             :     };
     226             : 
     227             :   template<>
     228             :     inline bool
     229             :     _Sp_counted_base<_S_single>::
     230             :     _M_add_ref_lock_nothrow() noexcept
     231             :     {
     232             :       if (_M_use_count == 0)
     233             :         return false;
     234             :       ++_M_use_count;
     235             :       return true;
     236             :     }
     237             : 
     238             :   template<>
     239             :     inline bool
     240             :     _Sp_counted_base<_S_mutex>::
     241             :     _M_add_ref_lock_nothrow() noexcept
     242             :     {
     243             :       __gnu_cxx::__scoped_lock sentry(*this);
     244             :       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
     245             :         {
     246             :           _M_use_count = 0;
     247             :           return false;
     248             :         }
     249             :       return true;
     250             :     }
     251             : 
     252             :   template<>
     253             :     inline bool
     254      214782 :     _Sp_counted_base<_S_atomic>::
     255             :     _M_add_ref_lock_nothrow() noexcept
     256             :     {
     257             :       // Perform lock-free add-if-not-zero operation.
     258      214782 :       _Atomic_word __count = _M_get_use_count();
     259             :       do
     260             :         {
     261      214968 :           if (__count == 0)
     262        2310 :             return false;
     263             :           // Replace the current counter value with the old value + 1, as
     264             :           // long as it's not changed meanwhile.
     265             :         }
     266      212658 :       while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
     267             :                                           true, __ATOMIC_ACQ_REL,
     268             :                                           __ATOMIC_RELAXED));
     269      212464 :       return true;
     270             :     }
     271             : 
     272             :   template<>
     273             :     inline void
     274             :     _Sp_counted_base<_S_single>::_M_add_ref_copy()
     275             :     { ++_M_use_count; }
     276             : 
     277             :   template<>
     278             :     inline void
     279             :     _Sp_counted_base<_S_single>::_M_release() noexcept
     280             :     {
     281             :       if (--_M_use_count == 0)
     282             :         {
     283             :           _M_dispose();
     284             :           if (--_M_weak_count == 0)
     285             :             _M_destroy();
     286             :         }
     287             :     }
     288             : 
     289             :   template<>
     290             :     inline void
     291             :     _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept
     292             :     { ++_M_weak_count; }
     293             : 
     294             :   template<>
     295             :     inline void
     296             :     _Sp_counted_base<_S_single>::_M_weak_release() noexcept
     297             :     {
     298             :       if (--_M_weak_count == 0)
     299             :         _M_destroy();
     300             :     }
     301             : 
     302             :   template<>
     303             :     inline long
     304             :     _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept
     305             :     { return _M_use_count; }
     306             : 
     307             : 
     308             :   // Forward declarations.
     309             :   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
     310             :     class __shared_ptr;
     311             : 
     312             :   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
     313             :     class __weak_ptr;
     314             : 
     315             :   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
     316             :     class __enable_shared_from_this;
     317             : 
     318             :   template<typename _Tp>
     319             :     class shared_ptr;
     320             : 
     321             :   template<typename _Tp>
     322             :     class weak_ptr;
     323             : 
     324             :   template<typename _Tp>
     325             :     struct owner_less;
     326             : 
     327             :   template<typename _Tp>
     328             :     class enable_shared_from_this;
     329             : 
     330             :   template<_Lock_policy _Lp = __default_lock_policy>
     331             :     class __weak_count;
     332             : 
     333             :   template<_Lock_policy _Lp = __default_lock_policy>
     334             :     class __shared_count;
     335             : 
     336             : 
     337             :   // Counted ptr with no deleter or allocator support
     338             :   template<typename _Ptr, _Lock_policy _Lp>
     339             :     class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
     340             :     {
     341             :     public:
     342             :       explicit
     343       25657 :       _Sp_counted_ptr(_Ptr __p) noexcept
     344       25657 :       : _M_ptr(__p) { }
     345             : 
     346             :       virtual void
     347       25656 :       _M_dispose() noexcept
     348       25656 :       { delete _M_ptr; }
     349             : 
     350             :       virtual void
     351       25656 :       _M_destroy() noexcept
     352       25656 :       { delete this; }
     353             : 
     354             :       virtual void*
     355           0 :       _M_get_deleter(const std::type_info&) noexcept
     356           0 :       { return nullptr; }
     357             : 
     358             :       _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
     359             :       _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
     360             : 
     361             :     private:
     362             :       _Ptr             _M_ptr;
     363             :     };
     364             : 
     365             :   template<>
     366             :     inline void
     367             :     _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { }
     368             : 
     369             :   template<>
     370             :     inline void
     371             :     _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { }
     372             : 
     373             :   template<>
     374             :     inline void
     375             :     _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { }
     376             : 
     377             :   template<int _Nm, typename _Tp,
     378             :            bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
     379             :     struct _Sp_ebo_helper;
     380             : 
     381             :   /// Specialization using EBO.
     382             :   template<int _Nm, typename _Tp>
     383             :     struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp
     384             :     {
     385      123409 :       explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { }
     386        1211 :       explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { }
     387             : 
     388             :       static _Tp&
     389     2333907 :       _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); }
     390             :     };
     391             : 
     392             :   /// Specialization not using EBO.
     393             :   template<int _Nm, typename _Tp>
     394             :     struct _Sp_ebo_helper<_Nm, _Tp, false>
     395             :     {
     396             :       explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { }
     397             :       explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(std::move(__tp)) { }
     398             : 
     399             :       static _Tp&
     400             :       _S_get(_Sp_ebo_helper& __eboh)
     401             :       { return __eboh._M_tp; }
     402             : 
     403             :     private:
     404             :       _Tp _M_tp;
     405             :     };
     406             : 
     407             :   // Support for custom deleter and/or allocator
     408             :   template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
     409             :     class _Sp_counted_deleter final : public _Sp_counted_base<_Lp>
     410             :     {
     411             :       class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc>
     412             :       {
     413             :         typedef _Sp_ebo_helper<0, _Deleter>       _Del_base;
     414             :         typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base;
     415             : 
     416             :       public:
     417        1211 :         _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
     418        1211 :         : _Del_base(std::move(__d)), _Alloc_base(__a), _M_ptr(__p)
     419        1211 :         { }
     420             : 
     421        1210 :         _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); }
     422        1209 :         _Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); }
     423             : 
     424             :         _Ptr _M_ptr;
     425             :       };
     426             : 
     427             :     public:
     428             :       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>;
     429             : 
     430             :       // __d(__p) must not throw.
     431        1211 :       _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
     432        1211 :       : _M_impl(__p, std::move(__d), _Alloc()) { }
     433             : 
     434             :       // __d(__p) must not throw.
     435           0 :       _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
     436           0 :       : _M_impl(__p, std::move(__d), __a) { }
     437             : 
     438        1209 :       ~_Sp_counted_deleter() noexcept { }
     439             : 
     440             :       virtual void
     441        1210 :       _M_dispose() noexcept
     442        1210 :       { _M_impl._M_del()(_M_impl._M_ptr); }
     443             : 
     444             :       virtual void
     445        1209 :       _M_destroy() noexcept
     446             :       {
     447        1209 :         __allocator_type __a(_M_impl._M_alloc());
     448        1209 :         __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
     449        1209 :         this->~_Sp_counted_deleter();
     450        1209 :       }
     451             : 
     452             :       virtual void*
     453           0 :       _M_get_deleter(const type_info& __ti [[__gnu__::__unused__]]) noexcept
     454             :       {
     455             : #if __cpp_rtti
     456             :         // _GLIBCXX_RESOLVE_LIB_DEFECTS
     457             :         // 2400. shared_ptr's get_deleter() should use addressof()
     458           0 :         return __ti == typeid(_Deleter)
     459           0 :           ? std::__addressof(_M_impl._M_del())
     460           0 :           : nullptr;
     461             : #else
     462             :         return nullptr;
     463             : #endif
     464             :       }
     465             : 
     466             :     private:
     467             :       _Impl _M_impl;
     468             :     };
     469             : 
     470             :   // helpers for make_shared / allocate_shared
     471             : 
     472             :   struct _Sp_make_shared_tag
     473             :   {
     474             :   private:
     475             :     template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
     476             :       friend class _Sp_counted_ptr_inplace;
     477             : 
     478             :     static const type_info&
     479           0 :     _S_ti() noexcept _GLIBCXX_VISIBILITY(default)
     480             :     {
     481             :       alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { };
     482           0 :       return reinterpret_cast<const type_info&>(__tag);
     483             :     }
     484             : 
     485             :     static bool _S_eq(const type_info&) noexcept;
     486             :   };
     487             : 
     488             :   template<typename _Alloc>
     489             :     struct _Sp_alloc_shared_tag
     490             :     {
     491             :       const _Alloc& _M_a;
     492             :     };
     493             : 
     494             :   template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
     495             :     class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
     496             :     {
     497             :       class _Impl : _Sp_ebo_helper<0, _Alloc>
     498             :       {
     499             :         typedef _Sp_ebo_helper<0, _Alloc> _A_base;
     500             : 
     501             :       public:
     502      122198 :         explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { }
     503             : 
     504     2331488 :         _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); }
     505             : 
     506             :         __gnu_cxx::__aligned_buffer<_Tp> _M_storage;
     507             :       };
     508             : 
     509             :     public:
     510             :       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
     511             : 
     512             :       // Alloc parameter is not a reference so doesn't alias anything in __args
     513             :       template<typename... _Args>
     514      122198 :         _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
     515      122198 :         : _M_impl(__a)
     516             :         {
     517             :           // _GLIBCXX_RESOLVE_LIB_DEFECTS
     518             :           // 2070.  allocate_shared should use allocator_traits<A>::construct
     519      122198 :           allocator_traits<_Alloc>::construct(__a, _M_ptr(),
     520             :               std::forward<_Args>(__args)...); // might throw
     521      122199 :         }
     522             : 
     523     1165736 :       ~_Sp_counted_ptr_inplace() noexcept { }
     524             : 
     525             :       virtual void
     526     1165752 :       _M_dispose() noexcept
     527             :       {
     528     1165752 :         allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
     529     1165752 :       }
     530             : 
     531             :       // Override because the allocator needs to know the dynamic type
     532             :       virtual void
     533     1165736 :       _M_destroy() noexcept
     534             :       {
     535     1165736 :         __allocator_type __a(_M_impl._M_alloc());
     536     1165736 :         __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
     537     1165736 :         this->~_Sp_counted_ptr_inplace();
     538     1165736 :       }
     539             : 
     540             :     private:
     541             :       friend class __shared_count<_Lp>; // To be able to call _M_ptr().
     542             : 
     543             :       // No longer used, but code compiled against old libstdc++ headers
     544             :       // might still call it from __shared_ptr ctor to get the pointer out.
     545             :       virtual void*
     546           0 :       _M_get_deleter(const std::type_info& __ti) noexcept override
     547             :       {
     548           0 :         auto __ptr = const_cast<typename remove_cv<_Tp>::type*>(_M_ptr());
     549             :         // Check for the fake type_info first, so we don't try to access it
     550             :         // as a real type_info object. Otherwise, check if it's the real
     551             :         // type_info for this class. With RTTI enabled we can check directly,
     552             :         // or call a library function to do it.
     553           0 :         if (&__ti == &_Sp_make_shared_tag::_S_ti()
     554           0 :             ||
     555             : #if __cpp_rtti
     556           0 :             __ti == typeid(_Sp_make_shared_tag)
     557             : #else
     558             :             _Sp_make_shared_tag::_S_eq(__ti)
     559             : #endif
     560             :            )
     561           0 :           return __ptr;
     562           0 :         return nullptr;
     563             :       }
     564             : 
     565     1410147 :       _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
     566             : 
     567             :       _Impl _M_impl;
     568             :     };
     569             : 
     570             :   // The default deleter for shared_ptr<T[]> and shared_ptr<T[N]>.
     571             :   struct __sp_array_delete
     572             :   {
     573             :     template<typename _Yp>
     574             :       void operator()(_Yp* __p) const { delete[] __p; }
     575             :   };
     576             : 
     577             :   template<_Lock_policy _Lp>
     578             :     class __shared_count
     579             :     {
     580             :       template<typename _Tp>
     581             :         struct __not_alloc_shared_tag { using type = void; };
     582             : 
     583             :       template<typename _Tp>
     584             :         struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { };
     585             : 
     586             :     public:
     587      553397 :       constexpr __shared_count() noexcept : _M_pi(0)
     588      553397 :       { }
     589             : 
     590             :       template<typename _Ptr>
     591             :         explicit
     592       25657 :         __shared_count(_Ptr __p) : _M_pi(0)
     593             :         {
     594             :           __try
     595             :             {
     596       25657 :               _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
     597             :             }
     598           0 :           __catch(...)
     599             :             {
     600           0 :               delete __p;
     601           0 :               __throw_exception_again;
     602             :             }
     603       25657 :         }
     604             : 
     605             :       template<typename _Ptr>
     606       25657 :         __shared_count(_Ptr __p, /* is_array = */ false_type)
     607       25657 :         : __shared_count(__p)
     608       25657 :         { }
     609             : 
     610             :       template<typename _Ptr>
     611             :         __shared_count(_Ptr __p, /* is_array = */ true_type)
     612             :         : __shared_count(__p, __sp_array_delete{}, allocator<void>())
     613             :         { }
     614             : 
     615             :       template<typename _Ptr, typename _Deleter,
     616             :                typename = typename __not_alloc_shared_tag<_Deleter>::type>
     617           0 :         __shared_count(_Ptr __p, _Deleter __d)
     618           0 :         : __shared_count(__p, std::move(__d), allocator<void>())
     619           0 :         { }
     620             : 
     621             :       template<typename _Ptr, typename _Deleter, typename _Alloc,
     622             :                typename = typename __not_alloc_shared_tag<_Deleter>::type>
     623           0 :         __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
     624             :         {
     625             :           typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
     626             :           __try
     627             :             {
     628           0 :               typename _Sp_cd_type::__allocator_type __a2(__a);
     629           0 :               auto __guard = std::__allocate_guarded(__a2);
     630           0 :               _Sp_cd_type* __mem = __guard.get();
     631           0 :               ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a));
     632           0 :               _M_pi = __mem;
     633           0 :               __guard = nullptr;
     634           0 :             }
     635           0 :           __catch(...)
     636             :             {
     637           0 :               __d(__p); // Call _Deleter on __p.
     638           0 :               __throw_exception_again;
     639             :             }
     640           0 :         }
     641             : 
     642             :       template<typename _Tp, typename _Alloc, typename... _Args>
     643      122198 :         __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a,
     644             :                        _Args&&... __args)
     645             :         {
     646             :           typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
     647      122198 :           typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
     648      122198 :           auto __guard = std::__allocate_guarded(__a2);
     649      122198 :           _Sp_cp_type* __mem = __guard.get();
     650      185033 :           auto __pi = ::new (__mem)
     651       62833 :             _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
     652      122197 :           __guard = nullptr;
     653      122197 :           _M_pi = __pi;
     654      122197 :           __p = __pi->_M_ptr();
     655      122199 :         }
     656             : 
     657             : #if _GLIBCXX_USE_DEPRECATED
     658             : #pragma GCC diagnostic push
     659             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     660             :       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
     661             :       template<typename _Tp>
     662             :         explicit
     663             :         __shared_count(std::auto_ptr<_Tp>&& __r);
     664             : #pragma GCC diagnostic pop
     665             : #endif
     666             : 
     667             :       // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
     668             :       template<typename _Tp, typename _Del>
     669             :         explicit
     670        1211 :         __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
     671             :         {
     672             :           // _GLIBCXX_RESOLVE_LIB_DEFECTS
     673             :           // 2415. Inconsistency between unique_ptr and shared_ptr
     674        1211 :           if (__r.get() == nullptr)
     675           0 :             return;
     676             : 
     677             :           using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
     678             :           using _Del2 = typename conditional<is_reference<_Del>::value,
     679             :               reference_wrapper<typename remove_reference<_Del>::type>,
     680             :               _Del>::type;
     681             :           using _Sp_cd_type
     682             :             = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
     683             :           using _Alloc = allocator<_Sp_cd_type>;
     684             :           using _Alloc_traits = allocator_traits<_Alloc>;
     685        1211 :           _Alloc __a;
     686        1211 :           _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
     687             :           // _GLIBCXX_RESOLVE_LIB_DEFECTS
     688             :           // 3548. shared_ptr construction from unique_ptr should move
     689             :           // (not copy) the deleter
     690        1211 :           _Alloc_traits::construct(__a, __mem, __r.release(),
     691        1211 :                                    std::forward<_Del>(__r.get_deleter()));
     692        1211 :           _M_pi = __mem;
     693        1211 :         }
     694             : 
     695             :       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
     696             :       explicit __shared_count(const __weak_count<_Lp>& __r);
     697             : 
     698             :       // Does not throw if __r._M_get_use_count() == 0, caller must check.
     699             :       explicit
     700             :       __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept;
     701             : 
     702     2874667 :       ~__shared_count() noexcept
     703             :       {
     704     2874667 :         if (_M_pi != nullptr)
     705     1706313 :           _M_pi->_M_release();
     706     2874786 :       }
     707             : 
     708     9021988 :       __shared_count(const __shared_count& __r) noexcept
     709     9021988 :       : _M_pi(__r._M_pi)
     710             :       {
     711     9021988 :         if (_M_pi != nullptr)
     712     9003246 :           _M_pi->_M_add_ref_copy();
     713     9022078 :       }
     714             : 
     715             :       __shared_count&
     716      106261 :       operator=(const __shared_count& __r) noexcept
     717             :       {
     718      106261 :         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
     719      106261 :         if (__tmp != _M_pi)
     720             :           {
     721      103656 :             if (__tmp != nullptr)
     722      103312 :               __tmp->_M_add_ref_copy();
     723      103657 :             if (_M_pi != nullptr)
     724       18437 :               _M_pi->_M_release();
     725      103657 :             _M_pi = __tmp;
     726             :           }
     727      106262 :         return *this;
     728             :       }
     729             : 
     730             :       void
     731      430390 :       _M_swap(__shared_count& __r) noexcept
     732             :       {
     733      430390 :         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
     734      430390 :         __r._M_pi = _M_pi;
     735      430390 :         _M_pi = __tmp;
     736      430390 :       }
     737             : 
     738             :       long
     739      136936 :       _M_get_use_count() const noexcept
     740      136936 :       { return _M_pi ? _M_pi->_M_get_use_count() : 0; }
     741             : 
     742             :       bool
     743        3030 :       _M_unique() const noexcept
     744        3030 :       { return this->_M_get_use_count() == 1; }
     745             : 
     746             :       void*
     747             :       _M_get_deleter(const std::type_info& __ti) const noexcept
     748             :       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; }
     749             : 
     750             :       bool
     751       32776 :       _M_less(const __shared_count& __rhs) const noexcept
     752       32776 :       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
     753             : 
     754             :       bool
     755             :       _M_less(const __weak_count<_Lp>& __rhs) const noexcept
     756             :       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
     757             : 
     758             :       // Friend function injected into enclosing namespace and found by ADL
     759             :       friend inline bool
     760             :       operator==(const __shared_count& __a, const __shared_count& __b) noexcept
     761             :       { return __a._M_pi == __b._M_pi; }
     762             : 
     763             :     private:
     764             :       friend class __weak_count<_Lp>;
     765             : 
     766             :       _Sp_counted_base<_Lp>*  _M_pi;
     767             :     };
     768             : 
     769             : 
     770             :   template<_Lock_policy _Lp>
     771             :     class __weak_count
     772             :     {
     773             :     public:
     774       11334 :       constexpr __weak_count() noexcept : _M_pi(nullptr)
     775       11334 :       { }
     776             : 
     777       90080 :       __weak_count(const __shared_count<_Lp>& __r) noexcept
     778       90080 :       : _M_pi(__r._M_pi)
     779             :       {
     780       90080 :         if (_M_pi != nullptr)
     781       90080 :           _M_pi->_M_weak_add_ref();
     782       90080 :       }
     783             : 
     784     5427275 :       __weak_count(const __weak_count& __r) noexcept
     785     5427275 :       : _M_pi(__r._M_pi)
     786             :       {
     787     5427275 :         if (_M_pi != nullptr)
     788     5427259 :           _M_pi->_M_weak_add_ref();
     789     5427277 :       }
     790             : 
     791      145190 :       __weak_count(__weak_count&& __r) noexcept
     792      145190 :       : _M_pi(__r._M_pi)
     793      145190 :       { __r._M_pi = nullptr; }
     794             : 
     795      346778 :       ~__weak_count() noexcept
     796             :       {
     797      346778 :         if (_M_pi != nullptr)
     798      199328 :           _M_pi->_M_weak_release();
     799      346781 :       }
     800             : 
     801             :       __weak_count&
     802       10725 :       operator=(const __shared_count<_Lp>& __r) noexcept
     803             :       {
     804       10725 :         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
     805       10725 :         if (__tmp != nullptr)
     806       10725 :           __tmp->_M_weak_add_ref();
     807       10725 :         if (_M_pi != nullptr)
     808         269 :           _M_pi->_M_weak_release();
     809       10725 :         _M_pi = __tmp;
     810       10725 :         return *this;
     811             :       }
     812             : 
     813             :       __weak_count&
     814             :       operator=(const __weak_count& __r) noexcept
     815             :       {
     816             :         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
     817             :         if (__tmp != nullptr)
     818             :           __tmp->_M_weak_add_ref();
     819             :         if (_M_pi != nullptr)
     820             :           _M_pi->_M_weak_release();
     821             :         _M_pi = __tmp;
     822             :         return *this;
     823             :       }
     824             : 
     825             :       __weak_count&
     826             :       operator=(__weak_count&& __r) noexcept
     827             :       {
     828             :         if (_M_pi != nullptr)
     829             :           _M_pi->_M_weak_release();
     830             :         _M_pi = __r._M_pi;
     831             :         __r._M_pi = nullptr;
     832             :         return *this;
     833             :       }
     834             : 
     835             :       void
     836          71 :       _M_swap(__weak_count& __r) noexcept
     837             :       {
     838          71 :         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
     839          71 :         __r._M_pi = _M_pi;
     840          71 :         _M_pi = __tmp;
     841          71 :       }
     842             : 
     843             :       long
     844        9539 :       _M_get_use_count() const noexcept
     845        9539 :       { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
     846             : 
     847             :       bool
     848        1794 :       _M_less(const __weak_count& __rhs) const noexcept
     849        1794 :       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
     850             : 
     851             :       bool
     852             :       _M_less(const __shared_count<_Lp>& __rhs) const noexcept
     853             :       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
     854             : 
     855             :       // Friend function injected into enclosing namespace and found by ADL
     856             :       friend inline bool
     857             :       operator==(const __weak_count& __a, const __weak_count& __b) noexcept
     858             :       { return __a._M_pi == __b._M_pi; }
     859             : 
     860             :     private:
     861             :       friend class __shared_count<_Lp>;
     862             : 
     863             :       _Sp_counted_base<_Lp>*  _M_pi;
     864             :     };
     865             : 
     866             :   // Now that __weak_count is defined we can define this constructor:
     867             :   template<_Lock_policy _Lp>
     868             :     inline
     869       81806 :     __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
     870       81806 :     : _M_pi(__r._M_pi)
     871             :     {
     872       81806 :       if (_M_pi == nullptr || !_M_pi->_M_add_ref_lock_nothrow())
     873           0 :         __throw_bad_weak_ptr();
     874       81806 :     }
     875             : 
     876             :   // Now that __weak_count is defined we can define this constructor:
     877             :   template<_Lock_policy _Lp>
     878             :     inline
     879      133920 :     __shared_count<_Lp>::
     880             :     __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept
     881      133920 :     : _M_pi(__r._M_pi)
     882             :     {
     883      133920 :       if (_M_pi && !_M_pi->_M_add_ref_lock_nothrow())
     884        2310 :         _M_pi = nullptr;
     885      133924 :     }
     886             : 
     887             : #define __cpp_lib_shared_ptr_arrays 201611L
     888             : 
     889             :   // Helper traits for shared_ptr of array:
     890             : 
     891             :   // A pointer type Y* is said to be compatible with a pointer type T* when
     892             :   // either Y* is convertible to T* or Y is U[N] and T is U cv [].
     893             :   template<typename _Yp_ptr, typename _Tp_ptr>
     894             :     struct __sp_compatible_with
     895             :     : false_type
     896             :     { };
     897             : 
     898             :   template<typename _Yp, typename _Tp>
     899             :     struct __sp_compatible_with<_Yp*, _Tp*>
     900             :     : is_convertible<_Yp*, _Tp*>::type
     901             :     { };
     902             : 
     903             :   template<typename _Up, size_t _Nm>
     904             :     struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]>
     905             :     : true_type
     906             :     { };
     907             : 
     908             :   template<typename _Up, size_t _Nm>
     909             :     struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]>
     910             :     : true_type
     911             :     { };
     912             : 
     913             :   template<typename _Up, size_t _Nm>
     914             :     struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]>
     915             :     : true_type
     916             :     { };
     917             : 
     918             :   template<typename _Up, size_t _Nm>
     919             :     struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]>
     920             :     : true_type
     921             :     { };
     922             : 
     923             :   // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N].
     924             :   template<typename _Up, size_t _Nm, typename _Yp, typename = void>
     925             :     struct __sp_is_constructible_arrN
     926             :     : false_type
     927             :     { };
     928             : 
     929             :   template<typename _Up, size_t _Nm, typename _Yp>
     930             :     struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
     931             :     : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
     932             :     { };
     933             : 
     934             :   // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[].
     935             :   template<typename _Up, typename _Yp, typename = void>
     936             :     struct __sp_is_constructible_arr
     937             :     : false_type
     938             :     { };
     939             : 
     940             :   template<typename _Up, typename _Yp>
     941             :     struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
     942             :     : is_convertible<_Yp(*)[], _Up(*)[]>::type
     943             :     { };
     944             : 
     945             :   // Trait to check if shared_ptr<T> can be constructed from Y*.
     946             :   template<typename _Tp, typename _Yp>
     947             :     struct __sp_is_constructible;
     948             : 
     949             :   // When T is U[N], Y(*)[N] shall be convertible to T*;
     950             :   template<typename _Up, size_t _Nm, typename _Yp>
     951             :     struct __sp_is_constructible<_Up[_Nm], _Yp>
     952             :     : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
     953             :     { };
     954             : 
     955             :   // when T is U[], Y(*)[] shall be convertible to T*;
     956             :   template<typename _Up, typename _Yp>
     957             :     struct __sp_is_constructible<_Up[], _Yp>
     958             :     : __sp_is_constructible_arr<_Up, _Yp>::type
     959             :     { };
     960             : 
     961             :   // otherwise, Y* shall be convertible to T*.
     962             :   template<typename _Tp, typename _Yp>
     963             :     struct __sp_is_constructible
     964             :     : is_convertible<_Yp*, _Tp*>::type
     965             :     { };
     966             : 
     967             : 
     968             :   // Define operator* and operator-> for shared_ptr<T>.
     969             :   template<typename _Tp, _Lock_policy _Lp,
     970             :            bool = is_array<_Tp>::value, bool = is_void<_Tp>::value>
     971             :     class __shared_ptr_access
     972             :     {
     973             :     public:
     974             :       using element_type = _Tp;
     975             : 
     976             :       element_type&
     977      369217 :       operator*() const noexcept
     978             :       {
     979      369217 :         __glibcxx_assert(_M_get() != nullptr);
     980      369217 :         return *_M_get();
     981             :       }
     982             : 
     983             :       element_type*
     984   186085809 :       operator->() const noexcept
     985             :       {
     986             :         _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
     987   186085809 :         return _M_get();
     988             :       }
     989             : 
     990             :     private:
     991             :       element_type*
     992   186455010 :       _M_get() const noexcept
     993   186455010 :       { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
     994             :     };
     995             : 
     996             :   // Define operator-> for shared_ptr<cv void>.
     997             :   template<typename _Tp, _Lock_policy _Lp>
     998             :     class __shared_ptr_access<_Tp, _Lp, false, true>
     999             :     {
    1000             :     public:
    1001             :       using element_type = _Tp;
    1002             : 
    1003             :       element_type*
    1004             :       operator->() const noexcept
    1005             :       {
    1006             :         auto __ptr = static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get();
    1007             :         _GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr);
    1008             :         return __ptr;
    1009             :       }
    1010             :     };
    1011             : 
    1012             :   // Define operator[] for shared_ptr<T[]> and shared_ptr<T[N]>.
    1013             :   template<typename _Tp, _Lock_policy _Lp>
    1014             :     class __shared_ptr_access<_Tp, _Lp, true, false>
    1015             :     {
    1016             :     public:
    1017             :       using element_type = typename remove_extent<_Tp>::type;
    1018             : 
    1019             : #if __cplusplus <= 201402L
    1020             :       [[__deprecated__("shared_ptr<T[]>::operator* is absent from C++17")]]
    1021             :       element_type&
    1022             :       operator*() const noexcept
    1023             :       {
    1024             :         __glibcxx_assert(_M_get() != nullptr);
    1025             :         return *_M_get();
    1026             :       }
    1027             : 
    1028             :       [[__deprecated__("shared_ptr<T[]>::operator-> is absent from C++17")]]
    1029             :       element_type*
    1030             :       operator->() const noexcept
    1031             :       {
    1032             :         _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
    1033             :         return _M_get();
    1034             :       }
    1035             : #endif
    1036             : 
    1037             :       element_type&
    1038             :       operator[](ptrdiff_t __i) const
    1039             :       {
    1040             :         __glibcxx_assert(_M_get() != nullptr);
    1041             :         __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value);
    1042             :         return _M_get()[__i];
    1043             :       }
    1044             : 
    1045             :     private:
    1046             :       element_type*
    1047             :       _M_get() const noexcept
    1048             :       { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
    1049             :     };
    1050             : 
    1051             :   template<typename _Tp, _Lock_policy _Lp>
    1052             :     class __shared_ptr
    1053             :     : public __shared_ptr_access<_Tp, _Lp>
    1054             :     {
    1055             :     public:
    1056             :       using element_type = typename remove_extent<_Tp>::type;
    1057             : 
    1058             :     private:
    1059             :       // Constraint for taking ownership of a pointer of type _Yp*:
    1060             :       template<typename _Yp>
    1061             :         using _SafeConv
    1062             :           = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type;
    1063             : 
    1064             :       // Constraint for construction from shared_ptr and weak_ptr:
    1065             :       template<typename _Yp, typename _Res = void>
    1066             :         using _Compatible = typename
    1067             :           enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
    1068             : 
    1069             :       // Constraint for assignment from shared_ptr and weak_ptr:
    1070             :       template<typename _Yp>
    1071             :         using _Assignable = _Compatible<_Yp, __shared_ptr&>;
    1072             : 
    1073             :       // Constraint for construction from unique_ptr:
    1074             :       template<typename _Yp, typename _Del, typename _Res = void,
    1075             :                typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer>
    1076             :         using _UniqCompatible = __enable_if_t<__and_<
    1077             :           __sp_compatible_with<_Yp*, _Tp*>,
    1078             :           is_convertible<_Ptr, element_type*>,
    1079             :           is_move_constructible<_Del>
    1080             :           >::value, _Res>;
    1081             : 
    1082             :       // Constraint for assignment from unique_ptr:
    1083             :       template<typename _Yp, typename _Del>
    1084             :         using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>;
    1085             : 
    1086             :     public:
    1087             : 
    1088             : #if __cplusplus > 201402L
    1089             :       using weak_type = __weak_ptr<_Tp, _Lp>;
    1090             : #endif
    1091             : 
    1092      251283 :       constexpr __shared_ptr() noexcept
    1093      251283 :       : _M_ptr(0), _M_refcount()
    1094      251283 :       { }
    1095             : 
    1096             :       template<typename _Yp, typename = _SafeConv<_Yp>>
    1097             :         explicit
    1098       25657 :         __shared_ptr(_Yp* __p)
    1099       25657 :         : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type())
    1100             :         {
    1101             :           static_assert( !is_void<_Yp>::value, "incomplete type" );
    1102             :           static_assert( sizeof(_Yp) > 0, "incomplete type" );
    1103       25657 :           _M_enable_shared_from_this_with(__p);
    1104       25657 :         }
    1105             : 
    1106             :       template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>>
    1107           0 :         __shared_ptr(_Yp* __p, _Deleter __d)
    1108           0 :         : _M_ptr(__p), _M_refcount(__p, std::move(__d))
    1109             :         {
    1110             :           static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
    1111             :               "deleter expression d(p) is well-formed");
    1112           0 :           _M_enable_shared_from_this_with(__p);
    1113           0 :         }
    1114             : 
    1115             :       template<typename _Yp, typename _Deleter, typename _Alloc,
    1116             :                typename = _SafeConv<_Yp>>
    1117             :         __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
    1118             :         : _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a))
    1119             :         {
    1120             :           static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
    1121             :               "deleter expression d(p) is well-formed");
    1122             :           _M_enable_shared_from_this_with(__p);
    1123             :         }
    1124             : 
    1125             :       template<typename _Deleter>
    1126             :         __shared_ptr(nullptr_t __p, _Deleter __d)
    1127             :         : _M_ptr(0), _M_refcount(__p, std::move(__d))
    1128             :         { }
    1129             : 
    1130             :       template<typename _Deleter, typename _Alloc>
    1131             :         __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
    1132             :         : _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a))
    1133             :         { }
    1134             : 
    1135             :       // Aliasing constructor
    1136             :       template<typename _Yp>
    1137      143228 :         __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r,
    1138             :                      element_type* __p) noexcept
    1139      143228 :         : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
    1140      143222 :         { }
    1141             : 
    1142             :       // Aliasing constructor
    1143             :       template<typename _Yp>
    1144             :         __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r,
    1145             :                      element_type* __p) noexcept
    1146             :         : _M_ptr(__p), _M_refcount()
    1147             :         {
    1148             :           _M_refcount._M_swap(__r._M_refcount);
    1149             :           __r._M_ptr = nullptr;
    1150             :         }
    1151             : 
    1152      889780 :       __shared_ptr(const __shared_ptr&) noexcept = default;
    1153       44529 :       __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
    1154     2874637 :       ~__shared_ptr() = default;
    1155             : 
    1156             :       template<typename _Yp, typename = _Compatible<_Yp>>
    1157        3080 :         __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
    1158        3080 :         : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
    1159        3080 :         { }
    1160             : 
    1161      279888 :       __shared_ptr(__shared_ptr&& __r) noexcept
    1162      279888 :       : _M_ptr(__r._M_ptr), _M_refcount()
    1163             :       {
    1164      279888 :         _M_refcount._M_swap(__r._M_refcount);
    1165      279888 :         __r._M_ptr = nullptr;
    1166      279888 :       }
    1167             : 
    1168             :       template<typename _Yp, typename = _Compatible<_Yp>>
    1169       21047 :         __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept
    1170       21047 :         : _M_ptr(__r._M_ptr), _M_refcount()
    1171             :         {
    1172       21047 :           _M_refcount._M_swap(__r._M_refcount);
    1173       21047 :           __r._M_ptr = nullptr;
    1174       21047 :         }
    1175             : 
    1176             :       template<typename _Yp, typename = _Compatible<_Yp>>
    1177       81111 :         explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r)
    1178       81111 :         : _M_refcount(__r._M_refcount) // may throw
    1179             :         {
    1180             :           // It is now safe to copy __r._M_ptr, as
    1181             :           // _M_refcount(__r._M_refcount) did not throw.
    1182       81111 :           _M_ptr = __r._M_ptr;
    1183       81111 :         }
    1184             : 
    1185             :       // If an exception is thrown this constructor has no effect.
    1186             :       template<typename _Yp, typename _Del,
    1187             :                typename = _UniqCompatible<_Yp, _Del>>
    1188        1211 :         __shared_ptr(unique_ptr<_Yp, _Del>&& __r)
    1189        1211 :         : _M_ptr(__r.get()), _M_refcount()
    1190             :         {
    1191        1211 :           auto __raw = __to_address(__r.get());
    1192        1211 :           _M_refcount = __shared_count<_Lp>(std::move(__r));
    1193        1211 :           _M_enable_shared_from_this_with(__raw);
    1194        1211 :         }
    1195             : 
    1196             : #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
    1197             :     protected:
    1198             :       // If an exception is thrown this constructor has no effect.
    1199             :       template<typename _Tp1, typename _Del,
    1200             :                typename enable_if<__and_<
    1201             :                  __not_<is_array<_Tp>>, is_array<_Tp1>,
    1202             :                  is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*>
    1203             :                >::value, bool>::type = true>
    1204             :         __shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete)
    1205             :         : _M_ptr(__r.get()), _M_refcount()
    1206             :         {
    1207             :           auto __raw = __to_address(__r.get());
    1208             :           _M_refcount = __shared_count<_Lp>(std::move(__r));
    1209             :           _M_enable_shared_from_this_with(__raw);
    1210             :         }
    1211             :     public:
    1212             : #endif
    1213             : 
    1214             : #if _GLIBCXX_USE_DEPRECATED
    1215             : #pragma GCC diagnostic push
    1216             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    1217             :       // Postcondition: use_count() == 1 and __r.get() == 0
    1218             :       template<typename _Yp, typename = _Compatible<_Yp>>
    1219             :         __shared_ptr(auto_ptr<_Yp>&& __r);
    1220             : #pragma GCC diagnostic pop
    1221             : #endif
    1222             : 
    1223             :       constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
    1224             : 
    1225             :       template<typename _Yp>
    1226             :         _Assignable<_Yp>
    1227          28 :         operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
    1228             :         {
    1229          28 :           _M_ptr = __r._M_ptr;
    1230          28 :           _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
    1231          28 :           return *this;
    1232             :         }
    1233             : 
    1234             : #if _GLIBCXX_USE_DEPRECATED
    1235             : #pragma GCC diagnostic push
    1236             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    1237             :       template<typename _Yp>
    1238             :         _Assignable<_Yp>
    1239             :         operator=(auto_ptr<_Yp>&& __r)
    1240             :         {
    1241             :           __shared_ptr(std::move(__r)).swap(*this);
    1242             :           return *this;
    1243             :         }
    1244             : #pragma GCC diagnostic pop
    1245             : #endif
    1246             : 
    1247             :       __shared_ptr&
    1248      116347 :       operator=(__shared_ptr&& __r) noexcept
    1249             :       {
    1250      116347 :         __shared_ptr(std::move(__r)).swap(*this);
    1251      116347 :         return *this;
    1252             :       }
    1253             : 
    1254             :       template<class _Yp>
    1255             :         _Assignable<_Yp>
    1256        1359 :         operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept
    1257             :         {
    1258        1359 :           __shared_ptr(std::move(__r)).swap(*this);
    1259        1359 :           return *this;
    1260             :         }
    1261             : 
    1262             :       template<typename _Yp, typename _Del>
    1263             :         _UniqAssignable<_Yp, _Del>
    1264           0 :         operator=(unique_ptr<_Yp, _Del>&& __r)
    1265             :         {
    1266           0 :           __shared_ptr(std::move(__r)).swap(*this);
    1267           0 :           return *this;
    1268             :         }
    1269             : 
    1270             :       void
    1271        3979 :       reset() noexcept
    1272        3979 :       { __shared_ptr().swap(*this); }
    1273             : 
    1274             :       template<typename _Yp>
    1275             :         _SafeConv<_Yp>
    1276        5897 :         reset(_Yp* __p) // _Yp must be complete.
    1277             :         {
    1278             :           // Catch self-reset errors.
    1279             :           __glibcxx_assert(__p == nullptr || __p != _M_ptr);
    1280        5897 :           __shared_ptr(__p).swap(*this);
    1281        5897 :         }
    1282             : 
    1283             :       template<typename _Yp, typename _Deleter>
    1284             :         _SafeConv<_Yp>
    1285             :         reset(_Yp* __p, _Deleter __d)
    1286             :         { __shared_ptr(__p, std::move(__d)).swap(*this); }
    1287             : 
    1288             :       template<typename _Yp, typename _Deleter, typename _Alloc>
    1289             :         _SafeConv<_Yp>
    1290             :         reset(_Yp* __p, _Deleter __d, _Alloc __a)
    1291             :         { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); }
    1292             : 
    1293             :       /// Return the stored pointer.
    1294             :       element_type*
    1295   186662700 :       get() const noexcept
    1296   186662700 :       { return _M_ptr; }
    1297             : 
    1298             :       /// Return true if the stored pointer is not null.
    1299    92714110 :       explicit operator bool() const noexcept
    1300    92714110 :       { return _M_ptr != nullptr; }
    1301             : 
    1302             :       /// Return true if use_count() == 1.
    1303             :       bool
    1304        3030 :       unique() const noexcept
    1305        3030 :       { return _M_refcount._M_unique(); }
    1306             : 
    1307             :       /// If *this owns a pointer, return the number of owners, otherwise zero.
    1308             :       long
    1309             :       use_count() const noexcept
    1310             :       { return _M_refcount._M_get_use_count(); }
    1311             : 
    1312             :       /// Exchange both the owned pointer and the stored pointer.
    1313             :       void
    1314      129475 :       swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
    1315             :       {
    1316      129475 :         std::swap(_M_ptr, __other._M_ptr);
    1317      129475 :         _M_refcount._M_swap(__other._M_refcount);
    1318      129475 :       }
    1319             : 
    1320             :       /** @brief Define an ordering based on ownership.
    1321             :        *
    1322             :        * This function defines a strict weak ordering between two shared_ptr
    1323             :        * or weak_ptr objects, such that one object is less than the other
    1324             :        * unless they share ownership of the same pointer, or are both empty.
    1325             :        * @{
    1326             :       */
    1327             :       template<typename _Tp1>
    1328             :         bool
    1329       32776 :         owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept
    1330       32776 :         { return _M_refcount._M_less(__rhs._M_refcount); }
    1331             : 
    1332             :       template<typename _Tp1>
    1333             :         bool
    1334             :         owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept
    1335             :         { return _M_refcount._M_less(__rhs._M_refcount); }
    1336             :       /// @}
    1337             : 
    1338             :     protected:
    1339             :       // This constructor is non-standard, it is used by allocate_shared.
    1340             :       template<typename _Alloc, typename... _Args>
    1341      122198 :         __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
    1342      122198 :         : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
    1343      122197 :         { _M_enable_shared_from_this_with(_M_ptr); }
    1344             : 
    1345             :       template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
    1346             :                typename... _Args>
    1347             :         friend __shared_ptr<_Tp1, _Lp1>
    1348             :         __allocate_shared(const _Alloc& __a, _Args&&... __args);
    1349             : 
    1350             :       // This constructor is used by __weak_ptr::lock() and
    1351             :       // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
    1352      133927 :       __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) noexcept
    1353      133927 :       : _M_refcount(__r._M_refcount, std::nothrow)
    1354             :       {
    1355      133928 :         _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr;
    1356      133921 :       }
    1357             : 
    1358             :       friend class __weak_ptr<_Tp, _Lp>;
    1359             : 
    1360             :     private:
    1361             : 
    1362             :       template<typename _Yp>
    1363             :         using __esft_base_t = decltype(__enable_shared_from_this_base(
    1364             :               std::declval<const __shared_count<_Lp>&>(),
    1365             :               std::declval<_Yp*>()));
    1366             : 
    1367             :       // Detect an accessible and unambiguous enable_shared_from_this base.
    1368             :       template<typename _Yp, typename = void>
    1369             :         struct __has_esft_base
    1370             :         : false_type { };
    1371             : 
    1372             :       template<typename _Yp>
    1373             :         struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
    1374             :         : __not_<is_array<_Tp>> { }; // No enable shared_from_this for arrays
    1375             : 
    1376             :       template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
    1377             :         typename enable_if<__has_esft_base<_Yp2>::value>::type
    1378        7897 :         _M_enable_shared_from_this_with(_Yp* __p) noexcept
    1379             :         {
    1380        7897 :           if (auto __base = __enable_shared_from_this_base(_M_refcount, __p))
    1381        7897 :             __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount);
    1382        7897 :         }
    1383             : 
    1384             :       template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
    1385             :         typename enable_if<!__has_esft_base<_Yp2>::value>::type
    1386      141168 :         _M_enable_shared_from_this_with(_Yp*) noexcept
    1387      141168 :         { }
    1388             : 
    1389             :       void*
    1390             :       _M_get_deleter(const std::type_info& __ti) const noexcept
    1391             :       { return _M_refcount._M_get_deleter(__ti); }
    1392             : 
    1393             :       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
    1394             :       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
    1395             : 
    1396             :       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
    1397             :         friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
    1398             : 
    1399             :       template<typename _Del, typename _Tp1>
    1400             :         friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept;
    1401             : 
    1402             :       element_type*        _M_ptr;         // Contained pointer.
    1403             :       __shared_count<_Lp>  _M_refcount;    // Reference counter.
    1404             :     };
    1405             : 
    1406             : 
    1407             :   // 20.7.2.2.7 shared_ptr comparisons
    1408             :   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
    1409             :     inline bool
    1410             :     operator==(const __shared_ptr<_Tp1, _Lp>& __a,
    1411             :                const __shared_ptr<_Tp2, _Lp>& __b) noexcept
    1412             :     { return __a.get() == __b.get(); }
    1413             : 
    1414             :   template<typename _Tp, _Lock_policy _Lp>
    1415             :     inline bool
    1416             :     operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
    1417             :     { return !__a; }
    1418             : 
    1419             : #ifdef __cpp_lib_three_way_comparison
    1420             :   template<typename _Tp, typename _Up, _Lock_policy _Lp>
    1421             :     inline strong_ordering
    1422             :     operator<=>(const __shared_ptr<_Tp, _Lp>& __a,
    1423             :                 const __shared_ptr<_Up, _Lp>& __b) noexcept
    1424             :     { return compare_three_way()(__a.get(), __b.get()); }
    1425             : 
    1426             :   template<typename _Tp, _Lock_policy _Lp>
    1427             :     inline strong_ordering
    1428             :     operator<=>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
    1429             :     {
    1430             :       using pointer = typename __shared_ptr<_Tp, _Lp>::element_type*;
    1431             :       return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
    1432             :     }
    1433             : #else
    1434             :   template<typename _Tp, _Lock_policy _Lp>
    1435             :     inline bool
    1436             :     operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
    1437             :     { return !__a; }
    1438             : 
    1439             :   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
    1440             :     inline bool
    1441             :     operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
    1442             :                const __shared_ptr<_Tp2, _Lp>& __b) noexcept
    1443             :     { return __a.get() != __b.get(); }
    1444             : 
    1445             :   template<typename _Tp, _Lock_policy _Lp>
    1446             :     inline bool
    1447             :     operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
    1448             :     { return (bool)__a; }
    1449             : 
    1450             :   template<typename _Tp, _Lock_policy _Lp>
    1451             :     inline bool
    1452             :     operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
    1453             :     { return (bool)__a; }
    1454             : 
    1455             :   template<typename _Tp, typename _Up, _Lock_policy _Lp>
    1456             :     inline bool
    1457             :     operator<(const __shared_ptr<_Tp, _Lp>& __a,
    1458             :               const __shared_ptr<_Up, _Lp>& __b) noexcept
    1459             :     {
    1460             :       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
    1461             :       using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type;
    1462             :       using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
    1463             :       return less<_Vp>()(__a.get(), __b.get());
    1464             :     }
    1465             : 
    1466             :   template<typename _Tp, _Lock_policy _Lp>
    1467             :     inline bool
    1468             :     operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
    1469             :     {
    1470             :       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
    1471             :       return less<_Tp_elt*>()(__a.get(), nullptr);
    1472             :     }
    1473             : 
    1474             :   template<typename _Tp, _Lock_policy _Lp>
    1475             :     inline bool
    1476             :     operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
    1477             :     {
    1478             :       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
    1479             :       return less<_Tp_elt*>()(nullptr, __a.get());
    1480             :     }
    1481             : 
    1482             :   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
    1483             :     inline bool
    1484             :     operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
    1485             :                const __shared_ptr<_Tp2, _Lp>& __b) noexcept
    1486             :     { return !(__b < __a); }
    1487             : 
    1488             :   template<typename _Tp, _Lock_policy _Lp>
    1489             :     inline bool
    1490             :     operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
    1491             :     { return !(nullptr < __a); }
    1492             : 
    1493             :   template<typename _Tp, _Lock_policy _Lp>
    1494             :     inline bool
    1495             :     operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
    1496             :     { return !(__a < nullptr); }
    1497             : 
    1498             :   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
    1499             :     inline bool
    1500             :     operator>(const __shared_ptr<_Tp1, _Lp>& __a,
    1501             :               const __shared_ptr<_Tp2, _Lp>& __b) noexcept
    1502             :     { return (__b < __a); }
    1503             : 
    1504             :   template<typename _Tp, _Lock_policy _Lp>
    1505             :     inline bool
    1506             :     operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
    1507             :     { return nullptr < __a; }
    1508             : 
    1509             :   template<typename _Tp, _Lock_policy _Lp>
    1510             :     inline bool
    1511             :     operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
    1512             :     { return __a < nullptr; }
    1513             : 
    1514             :   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
    1515             :     inline bool
    1516             :     operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
    1517             :                const __shared_ptr<_Tp2, _Lp>& __b) noexcept
    1518             :     { return !(__a < __b); }
    1519             : 
    1520             :   template<typename _Tp, _Lock_policy _Lp>
    1521             :     inline bool
    1522             :     operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
    1523             :     { return !(__a < nullptr); }
    1524             : 
    1525             :   template<typename _Tp, _Lock_policy _Lp>
    1526             :     inline bool
    1527             :     operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
    1528             :     { return !(nullptr < __a); }
    1529             : #endif // three-way comparison
    1530             : 
    1531             :   // 20.7.2.2.8 shared_ptr specialized algorithms.
    1532             :   template<typename _Tp, _Lock_policy _Lp>
    1533             :     inline void
    1534             :     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
    1535             :     { __a.swap(__b); }
    1536             : 
    1537             :   // 20.7.2.2.9 shared_ptr casts
    1538             : 
    1539             :   // The seemingly equivalent code:
    1540             :   // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
    1541             :   // will eventually result in undefined behaviour, attempting to
    1542             :   // delete the same object twice.
    1543             :   /// static_pointer_cast
    1544             :   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    1545             :     inline __shared_ptr<_Tp, _Lp>
    1546             :     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
    1547             :     {
    1548             :       using _Sp = __shared_ptr<_Tp, _Lp>;
    1549             :       return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
    1550             :     }
    1551             : 
    1552             :   // The seemingly equivalent code:
    1553             :   // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
    1554             :   // will eventually result in undefined behaviour, attempting to
    1555             :   // delete the same object twice.
    1556             :   /// const_pointer_cast
    1557             :   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    1558             :     inline __shared_ptr<_Tp, _Lp>
    1559             :     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
    1560             :     {
    1561             :       using _Sp = __shared_ptr<_Tp, _Lp>;
    1562             :       return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
    1563             :     }
    1564             : 
    1565             :   // The seemingly equivalent code:
    1566             :   // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
    1567             :   // will eventually result in undefined behaviour, attempting to
    1568             :   // delete the same object twice.
    1569             :   /// dynamic_pointer_cast
    1570             :   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    1571             :     inline __shared_ptr<_Tp, _Lp>
    1572             :     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
    1573             :     {
    1574             :       using _Sp = __shared_ptr<_Tp, _Lp>;
    1575             :       if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
    1576             :         return _Sp(__r, __p);
    1577             :       return _Sp();
    1578             :     }
    1579             : 
    1580             : #if __cplusplus > 201402L
    1581             :   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    1582             :     inline __shared_ptr<_Tp, _Lp>
    1583             :     reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
    1584             :     {
    1585             :       using _Sp = __shared_ptr<_Tp, _Lp>;
    1586             :       return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
    1587             :     }
    1588             : #endif
    1589             : 
    1590             :   template<typename _Tp, _Lock_policy _Lp>
    1591             :     class __weak_ptr
    1592             :     {
    1593             :       template<typename _Yp, typename _Res = void>
    1594             :         using _Compatible = typename
    1595             :           enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
    1596             : 
    1597             :       // Constraint for assignment from shared_ptr and weak_ptr:
    1598             :       template<typename _Yp>
    1599             :         using _Assignable = _Compatible<_Yp, __weak_ptr&>;
    1600             : 
    1601             :     public:
    1602             :       using element_type = typename remove_extent<_Tp>::type;
    1603             : 
    1604       11334 :       constexpr __weak_ptr() noexcept
    1605       11334 :       : _M_ptr(nullptr), _M_refcount()
    1606       11334 :       { }
    1607             : 
    1608      108216 :       __weak_ptr(const __weak_ptr&) noexcept = default;
    1609             : 
    1610      346785 :       ~__weak_ptr() = default;
    1611             : 
    1612             :       // The "obvious" converting constructor implementation:
    1613             :       //
    1614             :       //  template<typename _Tp1>
    1615             :       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    1616             :       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    1617             :       //    { }
    1618             :       //
    1619             :       // has a serious problem.
    1620             :       //
    1621             :       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
    1622             :       //  conversion may require access to *__r._M_ptr (virtual inheritance).
    1623             :       //
    1624             :       // It is not possible to avoid spurious access violations since
    1625             :       // in multithreaded programs __r._M_ptr may be invalidated at any point.
    1626             :       template<typename _Yp, typename = _Compatible<_Yp>>
    1627             :         __weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept
    1628             :         : _M_refcount(__r._M_refcount)
    1629             :         { _M_ptr = __r.lock().get(); }
    1630             : 
    1631             :       template<typename _Yp, typename = _Compatible<_Yp>>
    1632       80674 :         __weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
    1633       80674 :         : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
    1634       80674 :         { }
    1635             : 
    1636      145194 :       __weak_ptr(__weak_ptr&& __r) noexcept
    1637      145194 :       : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
    1638      145190 :       { __r._M_ptr = nullptr; }
    1639             : 
    1640             :       template<typename _Yp, typename = _Compatible<_Yp>>
    1641             :         __weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept
    1642             :         : _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount))
    1643             :         { __r._M_ptr = nullptr; }
    1644             : 
    1645             :       __weak_ptr&
    1646             :       operator=(const __weak_ptr& __r) noexcept = default;
    1647             : 
    1648             :       template<typename _Yp>
    1649             :         _Assignable<_Yp>
    1650             :         operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept
    1651             :         {
    1652             :           _M_ptr = __r.lock().get();
    1653             :           _M_refcount = __r._M_refcount;
    1654             :           return *this;
    1655             :         }
    1656             : 
    1657             :       template<typename _Yp>
    1658             :         _Assignable<_Yp>
    1659        2828 :         operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
    1660             :         {
    1661        2828 :           _M_ptr = __r._M_ptr;
    1662        2828 :           _M_refcount = __r._M_refcount;
    1663        2828 :           return *this;
    1664             :         }
    1665             : 
    1666             :       __weak_ptr&
    1667           0 :       operator=(__weak_ptr&& __r) noexcept
    1668             :       {
    1669           0 :         __weak_ptr(std::move(__r)).swap(*this);
    1670           0 :         return *this;
    1671             :       }
    1672             : 
    1673             :       template<typename _Yp>
    1674             :         _Assignable<_Yp>
    1675             :         operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept
    1676             :         {
    1677             :           _M_ptr = __r.lock().get();
    1678             :           _M_refcount = std::move(__r._M_refcount);
    1679             :           __r._M_ptr = nullptr;
    1680             :           return *this;
    1681             :         }
    1682             : 
    1683             :       __shared_ptr<_Tp, _Lp>
    1684             :       lock() const noexcept
    1685             :       { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); }
    1686             : 
    1687             :       long
    1688        7897 :       use_count() const noexcept
    1689        7897 :       { return _M_refcount._M_get_use_count(); }
    1690             : 
    1691             :       bool
    1692        1642 :       expired() const noexcept
    1693        1642 :       { return _M_refcount._M_get_use_count() == 0; }
    1694             : 
    1695             :       template<typename _Tp1>
    1696             :         bool
    1697             :         owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept
    1698             :         { return _M_refcount._M_less(__rhs._M_refcount); }
    1699             : 
    1700             :       template<typename _Tp1>
    1701             :         bool
    1702        1794 :         owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept
    1703        1794 :         { return _M_refcount._M_less(__rhs._M_refcount); }
    1704             : 
    1705             :       void
    1706          69 :       reset() noexcept
    1707          69 :       { __weak_ptr().swap(*this); }
    1708             : 
    1709             :       void
    1710          71 :       swap(__weak_ptr& __s) noexcept
    1711             :       {
    1712          71 :         std::swap(_M_ptr, __s._M_ptr);
    1713          71 :         _M_refcount._M_swap(__s._M_refcount);
    1714          71 :       }
    1715             : 
    1716             :     private:
    1717             :       // Used by __enable_shared_from_this.
    1718             :       void
    1719        7897 :       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
    1720             :       {
    1721        7897 :         if (use_count() == 0)
    1722             :           {
    1723        7897 :             _M_ptr = __ptr;
    1724        7897 :             _M_refcount = __refcount;
    1725             :           }
    1726        7897 :       }
    1727             : 
    1728             :       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
    1729             :       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
    1730             :       friend class __enable_shared_from_this<_Tp, _Lp>;
    1731             :       friend class enable_shared_from_this<_Tp>;
    1732             : 
    1733             :       element_type*      _M_ptr;         // Contained pointer.
    1734             :       __weak_count<_Lp>  _M_refcount;    // Reference counter.
    1735             :     };
    1736             : 
    1737             :   // 20.7.2.3.6 weak_ptr specialized algorithms.
    1738             :   template<typename _Tp, _Lock_policy _Lp>
    1739             :     inline void
    1740             :     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
    1741             :     { __a.swap(__b); }
    1742             : 
    1743             :   template<typename _Tp, typename _Tp1>
    1744             :     struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
    1745             :     {
    1746             :       bool
    1747        7390 :       operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept
    1748        7390 :       { return __lhs.owner_before(__rhs); }
    1749             : 
    1750             :       bool
    1751             :       operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept
    1752             :       { return __lhs.owner_before(__rhs); }
    1753             : 
    1754             :       bool
    1755             :       operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept
    1756             :       { return __lhs.owner_before(__rhs); }
    1757             :     };
    1758             : 
    1759             :   template<>
    1760             :     struct _Sp_owner_less<void, void>
    1761             :     {
    1762             :       template<typename _Tp, typename _Up>
    1763             :         auto
    1764             :         operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept
    1765             :         -> decltype(__lhs.owner_before(__rhs))
    1766             :         { return __lhs.owner_before(__rhs); }
    1767             : 
    1768             :       using is_transparent = void;
    1769             :     };
    1770             : 
    1771             :   template<typename _Tp, _Lock_policy _Lp>
    1772             :     struct owner_less<__shared_ptr<_Tp, _Lp>>
    1773             :     : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
    1774             :     { };
    1775             : 
    1776             :   template<typename _Tp, _Lock_policy _Lp>
    1777             :     struct owner_less<__weak_ptr<_Tp, _Lp>>
    1778             :     : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
    1779             :     { };
    1780             : 
    1781             : 
    1782             :   template<typename _Tp, _Lock_policy _Lp>
    1783             :     class __enable_shared_from_this
    1784             :     {
    1785             :     protected:
    1786             :       constexpr __enable_shared_from_this() noexcept { }
    1787             : 
    1788             :       __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
    1789             : 
    1790             :       __enable_shared_from_this&
    1791             :       operator=(const __enable_shared_from_this&) noexcept
    1792             :       { return *this; }
    1793             : 
    1794             :       ~__enable_shared_from_this() { }
    1795             : 
    1796             :     public:
    1797             :       __shared_ptr<_Tp, _Lp>
    1798             :       shared_from_this()
    1799             :       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
    1800             : 
    1801             :       __shared_ptr<const _Tp, _Lp>
    1802             :       shared_from_this() const
    1803             :       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
    1804             : 
    1805             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
    1806             :       __weak_ptr<_Tp, _Lp>
    1807             :       weak_from_this() noexcept
    1808             :       { return this->_M_weak_this; }
    1809             : 
    1810             :       __weak_ptr<const _Tp, _Lp>
    1811             :       weak_from_this() const noexcept
    1812             :       { return this->_M_weak_this; }
    1813             : #endif
    1814             : 
    1815             :     private:
    1816             :       template<typename _Tp1>
    1817             :         void
    1818             :         _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
    1819             :         { _M_weak_this._M_assign(__p, __n); }
    1820             : 
    1821             :       friend const __enable_shared_from_this*
    1822             :       __enable_shared_from_this_base(const __shared_count<_Lp>&,
    1823             :                                      const __enable_shared_from_this* __p)
    1824             :       { return __p; }
    1825             : 
    1826             :       template<typename, _Lock_policy>
    1827             :         friend class __shared_ptr;
    1828             : 
    1829             :       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
    1830             :     };
    1831             : 
    1832             :   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
    1833             :            typename _Alloc, typename... _Args>
    1834             :     inline __shared_ptr<_Tp, _Lp>
    1835             :     __allocate_shared(const _Alloc& __a, _Args&&... __args)
    1836             :     {
    1837             :       static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported");
    1838             : 
    1839             :       return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a},
    1840             :                                     std::forward<_Args>(__args)...);
    1841             :     }
    1842             : 
    1843             :   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
    1844             :            typename... _Args>
    1845             :     inline __shared_ptr<_Tp, _Lp>
    1846             :     __make_shared(_Args&&... __args)
    1847             :     {
    1848             :       typedef typename std::remove_const<_Tp>::type _Tp_nc;
    1849             :       return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
    1850             :                                               std::forward<_Args>(__args)...);
    1851             :     }
    1852             : 
    1853             :   /// std::hash specialization for __shared_ptr.
    1854             :   template<typename _Tp, _Lock_policy _Lp>
    1855             :     struct hash<__shared_ptr<_Tp, _Lp>>
    1856             :     : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
    1857             :     {
    1858             :       size_t
    1859             :       operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
    1860             :       {
    1861             :         return hash<typename __shared_ptr<_Tp, _Lp>::element_type*>()(
    1862             :             __s.get());
    1863             :       }
    1864             :     };
    1865             : 
    1866             : _GLIBCXX_END_NAMESPACE_VERSION
    1867             : } // namespace
    1868             : 
    1869             : #endif // _SHARED_PTR_BASE_H

Generated by: LCOV version 1.14