LCOV - code coverage report
Current view: top level - usr/include/c++/4.9/bits - shared_ptr_base.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 148 224 66.1 %
Date: 2016-11-29 15:07:43 Functions: 176 393 44.8 %

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

Generated by: LCOV version 1.11