xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/shared_ptr_base.h (revision 23f5f46327e37e7811da3520f4bb933f9489322f)
11debfc3dSmrg // shared_ptr and weak_ptr implementation details -*- C++ -*-
21debfc3dSmrg 
38feb0f0bSmrg // Copyright (C) 2007-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg 
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg 
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg 
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg 
251debfc3dSmrg // GCC Note: Based on files from version 1.32.0 of the Boost library.
261debfc3dSmrg 
271debfc3dSmrg //  shared_count.hpp
281debfc3dSmrg //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
291debfc3dSmrg 
301debfc3dSmrg //  shared_ptr.hpp
311debfc3dSmrg //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
321debfc3dSmrg //  Copyright (C) 2001, 2002, 2003 Peter Dimov
331debfc3dSmrg 
341debfc3dSmrg //  weak_ptr.hpp
351debfc3dSmrg //  Copyright (C) 2001, 2002, 2003 Peter Dimov
361debfc3dSmrg 
371debfc3dSmrg //  enable_shared_from_this.hpp
381debfc3dSmrg //  Copyright (C) 2002 Peter Dimov
391debfc3dSmrg 
401debfc3dSmrg // Distributed under the Boost Software License, Version 1.0. (See
411debfc3dSmrg // accompanying file LICENSE_1_0.txt or copy at
421debfc3dSmrg // http://www.boost.org/LICENSE_1_0.txt)
431debfc3dSmrg 
441debfc3dSmrg /** @file bits/shared_ptr_base.h
451debfc3dSmrg  *  This is an internal header file, included by other library headers.
461debfc3dSmrg  *  Do not attempt to use it directly. @headername{memory}
471debfc3dSmrg  */
481debfc3dSmrg 
491debfc3dSmrg #ifndef _SHARED_PTR_BASE_H
501debfc3dSmrg #define _SHARED_PTR_BASE_H 1
511debfc3dSmrg 
521debfc3dSmrg #include <typeinfo>
531debfc3dSmrg #include <bits/allocated_ptr.h>
541debfc3dSmrg #include <bits/refwrap.h>
551debfc3dSmrg #include <bits/stl_function.h>
561debfc3dSmrg #include <ext/aligned_buffer.h>
578feb0f0bSmrg #if __cplusplus > 201703L
588feb0f0bSmrg # include <compare>
598feb0f0bSmrg #endif
601debfc3dSmrg 
_GLIBCXX_VISIBILITY(default)611debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
621debfc3dSmrg {
631debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
641debfc3dSmrg 
651debfc3dSmrg #if _GLIBCXX_USE_DEPRECATED
66a2dc1f3fSmrg #pragma GCC diagnostic push
67a2dc1f3fSmrg #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
681debfc3dSmrg   template<typename> class auto_ptr;
69a2dc1f3fSmrg #pragma GCC diagnostic pop
701debfc3dSmrg #endif
711debfc3dSmrg 
721debfc3dSmrg  /**
731debfc3dSmrg    *  @brief  Exception possibly thrown by @c shared_ptr.
741debfc3dSmrg    *  @ingroup exceptions
751debfc3dSmrg    */
761debfc3dSmrg   class bad_weak_ptr : public std::exception
771debfc3dSmrg   {
781debfc3dSmrg   public:
791debfc3dSmrg     virtual char const* what() const noexcept;
801debfc3dSmrg 
811debfc3dSmrg     virtual ~bad_weak_ptr() noexcept;
821debfc3dSmrg   };
831debfc3dSmrg 
841debfc3dSmrg   // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
851debfc3dSmrg   inline void
861debfc3dSmrg   __throw_bad_weak_ptr()
871debfc3dSmrg   { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
881debfc3dSmrg 
891debfc3dSmrg   using __gnu_cxx::_Lock_policy;
901debfc3dSmrg   using __gnu_cxx::__default_lock_policy;
911debfc3dSmrg   using __gnu_cxx::_S_single;
921debfc3dSmrg   using __gnu_cxx::_S_mutex;
931debfc3dSmrg   using __gnu_cxx::_S_atomic;
941debfc3dSmrg 
951debfc3dSmrg   // Empty helper class except when the template argument is _S_mutex.
961debfc3dSmrg   template<_Lock_policy _Lp>
971debfc3dSmrg     class _Mutex_base
981debfc3dSmrg     {
991debfc3dSmrg     protected:
1001debfc3dSmrg       // The atomic policy uses fully-fenced builtins, single doesn't care.
1011debfc3dSmrg       enum { _S_need_barriers = 0 };
1021debfc3dSmrg     };
1031debfc3dSmrg 
1041debfc3dSmrg   template<>
1051debfc3dSmrg     class _Mutex_base<_S_mutex>
1061debfc3dSmrg     : public __gnu_cxx::__mutex
1071debfc3dSmrg     {
1081debfc3dSmrg     protected:
1091debfc3dSmrg       // This policy is used when atomic builtins are not available.
1101debfc3dSmrg       // The replacement atomic operations might not have the necessary
1111debfc3dSmrg       // memory barriers.
1121debfc3dSmrg       enum { _S_need_barriers = 1 };
1131debfc3dSmrg     };
1141debfc3dSmrg 
1151debfc3dSmrg   template<_Lock_policy _Lp = __default_lock_policy>
1161debfc3dSmrg     class _Sp_counted_base
1171debfc3dSmrg     : public _Mutex_base<_Lp>
1181debfc3dSmrg     {
1191debfc3dSmrg     public:
1201debfc3dSmrg       _Sp_counted_base() noexcept
1211debfc3dSmrg       : _M_use_count(1), _M_weak_count(1) { }
1221debfc3dSmrg 
1231debfc3dSmrg       virtual
1241debfc3dSmrg       ~_Sp_counted_base() noexcept
1251debfc3dSmrg       { }
1261debfc3dSmrg 
1271debfc3dSmrg       // Called when _M_use_count drops to zero, to release the resources
1281debfc3dSmrg       // managed by *this.
1291debfc3dSmrg       virtual void
1301debfc3dSmrg       _M_dispose() noexcept = 0;
1311debfc3dSmrg 
1321debfc3dSmrg       // Called when _M_weak_count drops to zero.
1331debfc3dSmrg       virtual void
1341debfc3dSmrg       _M_destroy() noexcept
1351debfc3dSmrg       { delete this; }
1361debfc3dSmrg 
1371debfc3dSmrg       virtual void*
1381debfc3dSmrg       _M_get_deleter(const std::type_info&) noexcept = 0;
1391debfc3dSmrg 
1401debfc3dSmrg       void
1411debfc3dSmrg       _M_add_ref_copy()
1421debfc3dSmrg       { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
1431debfc3dSmrg 
1441debfc3dSmrg       void
1451debfc3dSmrg       _M_add_ref_lock();
1461debfc3dSmrg 
1471debfc3dSmrg       bool
1481debfc3dSmrg       _M_add_ref_lock_nothrow();
1491debfc3dSmrg 
1501debfc3dSmrg       void
1511debfc3dSmrg       _M_release() noexcept
1521debfc3dSmrg       {
1531debfc3dSmrg         // Be race-detector-friendly.  For more info see bits/c++config.
1541debfc3dSmrg         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
1551debfc3dSmrg 	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
1561debfc3dSmrg 	  {
1571debfc3dSmrg             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
1581debfc3dSmrg 	    _M_dispose();
1591debfc3dSmrg 	    // There must be a memory barrier between dispose() and destroy()
1601debfc3dSmrg 	    // to ensure that the effects of dispose() are observed in the
1611debfc3dSmrg 	    // thread that runs destroy().
1621debfc3dSmrg 	    // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
1631debfc3dSmrg 	    if (_Mutex_base<_Lp>::_S_need_barriers)
1641debfc3dSmrg 	      {
1651debfc3dSmrg 		__atomic_thread_fence (__ATOMIC_ACQ_REL);
1661debfc3dSmrg 	      }
1671debfc3dSmrg 
1681debfc3dSmrg             // Be race-detector-friendly.  For more info see bits/c++config.
1691debfc3dSmrg             _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
1701debfc3dSmrg 	    if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
1711debfc3dSmrg 						       -1) == 1)
1721debfc3dSmrg               {
1731debfc3dSmrg                 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
1741debfc3dSmrg 	        _M_destroy();
1751debfc3dSmrg               }
1761debfc3dSmrg 	  }
1771debfc3dSmrg       }
1781debfc3dSmrg 
1791debfc3dSmrg       void
1801debfc3dSmrg       _M_weak_add_ref() noexcept
1811debfc3dSmrg       { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
1821debfc3dSmrg 
1831debfc3dSmrg       void
1841debfc3dSmrg       _M_weak_release() noexcept
1851debfc3dSmrg       {
1861debfc3dSmrg         // Be race-detector-friendly. For more info see bits/c++config.
1871debfc3dSmrg         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
1881debfc3dSmrg 	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
1891debfc3dSmrg 	  {
1901debfc3dSmrg             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
1911debfc3dSmrg 	    if (_Mutex_base<_Lp>::_S_need_barriers)
1921debfc3dSmrg 	      {
1931debfc3dSmrg 	        // See _M_release(),
1941debfc3dSmrg 	        // destroy() must observe results of dispose()
1951debfc3dSmrg 		__atomic_thread_fence (__ATOMIC_ACQ_REL);
1961debfc3dSmrg 	      }
1971debfc3dSmrg 	    _M_destroy();
1981debfc3dSmrg 	  }
1991debfc3dSmrg       }
2001debfc3dSmrg 
2011debfc3dSmrg       long
2021debfc3dSmrg       _M_get_use_count() const noexcept
2031debfc3dSmrg       {
2041debfc3dSmrg         // No memory barrier is used here so there is no synchronization
2051debfc3dSmrg         // with other threads.
2061debfc3dSmrg         return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
2071debfc3dSmrg       }
2081debfc3dSmrg 
2091debfc3dSmrg     private:
2101debfc3dSmrg       _Sp_counted_base(_Sp_counted_base const&) = delete;
2111debfc3dSmrg       _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
2121debfc3dSmrg 
2131debfc3dSmrg       _Atomic_word  _M_use_count;     // #shared
2141debfc3dSmrg       _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
2151debfc3dSmrg     };
2161debfc3dSmrg 
2171debfc3dSmrg   template<>
2181debfc3dSmrg     inline void
2191debfc3dSmrg     _Sp_counted_base<_S_single>::
2201debfc3dSmrg     _M_add_ref_lock()
2211debfc3dSmrg     {
2221debfc3dSmrg       if (_M_use_count == 0)
2231debfc3dSmrg 	__throw_bad_weak_ptr();
2241debfc3dSmrg       ++_M_use_count;
2251debfc3dSmrg     }
2261debfc3dSmrg 
2271debfc3dSmrg   template<>
2281debfc3dSmrg     inline void
2291debfc3dSmrg     _Sp_counted_base<_S_mutex>::
2301debfc3dSmrg     _M_add_ref_lock()
2311debfc3dSmrg     {
2321debfc3dSmrg       __gnu_cxx::__scoped_lock sentry(*this);
2331debfc3dSmrg       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
2341debfc3dSmrg 	{
2351debfc3dSmrg 	  _M_use_count = 0;
2361debfc3dSmrg 	  __throw_bad_weak_ptr();
2371debfc3dSmrg 	}
2381debfc3dSmrg     }
2391debfc3dSmrg 
2401debfc3dSmrg   template<>
2411debfc3dSmrg     inline void
2421debfc3dSmrg     _Sp_counted_base<_S_atomic>::
2431debfc3dSmrg     _M_add_ref_lock()
2441debfc3dSmrg     {
2451debfc3dSmrg       // Perform lock-free add-if-not-zero operation.
2461debfc3dSmrg       _Atomic_word __count = _M_get_use_count();
2471debfc3dSmrg       do
2481debfc3dSmrg 	{
2491debfc3dSmrg 	  if (__count == 0)
2501debfc3dSmrg 	    __throw_bad_weak_ptr();
2511debfc3dSmrg 	  // Replace the current counter value with the old value + 1, as
2521debfc3dSmrg 	  // long as it's not changed meanwhile.
2531debfc3dSmrg 	}
2541debfc3dSmrg       while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
2551debfc3dSmrg 					  true, __ATOMIC_ACQ_REL,
2561debfc3dSmrg 					  __ATOMIC_RELAXED));
2571debfc3dSmrg     }
2581debfc3dSmrg 
2591debfc3dSmrg   template<>
2601debfc3dSmrg     inline bool
2611debfc3dSmrg     _Sp_counted_base<_S_single>::
2621debfc3dSmrg     _M_add_ref_lock_nothrow()
2631debfc3dSmrg     {
2641debfc3dSmrg       if (_M_use_count == 0)
2651debfc3dSmrg 	return false;
2661debfc3dSmrg       ++_M_use_count;
2671debfc3dSmrg       return true;
2681debfc3dSmrg     }
2691debfc3dSmrg 
2701debfc3dSmrg   template<>
2711debfc3dSmrg     inline bool
2721debfc3dSmrg     _Sp_counted_base<_S_mutex>::
2731debfc3dSmrg     _M_add_ref_lock_nothrow()
2741debfc3dSmrg     {
2751debfc3dSmrg       __gnu_cxx::__scoped_lock sentry(*this);
2761debfc3dSmrg       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
2771debfc3dSmrg 	{
2781debfc3dSmrg 	  _M_use_count = 0;
2791debfc3dSmrg 	  return false;
2801debfc3dSmrg 	}
2811debfc3dSmrg       return true;
2821debfc3dSmrg     }
2831debfc3dSmrg 
2841debfc3dSmrg   template<>
2851debfc3dSmrg     inline bool
2861debfc3dSmrg     _Sp_counted_base<_S_atomic>::
2871debfc3dSmrg     _M_add_ref_lock_nothrow()
2881debfc3dSmrg     {
2891debfc3dSmrg       // Perform lock-free add-if-not-zero operation.
2901debfc3dSmrg       _Atomic_word __count = _M_get_use_count();
2911debfc3dSmrg       do
2921debfc3dSmrg 	{
2931debfc3dSmrg 	  if (__count == 0)
2941debfc3dSmrg 	    return false;
2951debfc3dSmrg 	  // Replace the current counter value with the old value + 1, as
2961debfc3dSmrg 	  // long as it's not changed meanwhile.
2971debfc3dSmrg 	}
2981debfc3dSmrg       while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
2991debfc3dSmrg 					  true, __ATOMIC_ACQ_REL,
3001debfc3dSmrg 					  __ATOMIC_RELAXED));
3011debfc3dSmrg       return true;
3021debfc3dSmrg     }
3031debfc3dSmrg 
3041debfc3dSmrg   template<>
3051debfc3dSmrg     inline void
3061debfc3dSmrg     _Sp_counted_base<_S_single>::_M_add_ref_copy()
3071debfc3dSmrg     { ++_M_use_count; }
3081debfc3dSmrg 
3091debfc3dSmrg   template<>
3101debfc3dSmrg     inline void
3111debfc3dSmrg     _Sp_counted_base<_S_single>::_M_release() noexcept
3121debfc3dSmrg     {
3131debfc3dSmrg       if (--_M_use_count == 0)
3141debfc3dSmrg         {
3151debfc3dSmrg           _M_dispose();
3161debfc3dSmrg           if (--_M_weak_count == 0)
3171debfc3dSmrg             _M_destroy();
3181debfc3dSmrg         }
3191debfc3dSmrg     }
3201debfc3dSmrg 
3211debfc3dSmrg   template<>
3221debfc3dSmrg     inline void
3231debfc3dSmrg     _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept
3241debfc3dSmrg     { ++_M_weak_count; }
3251debfc3dSmrg 
3261debfc3dSmrg   template<>
3271debfc3dSmrg     inline void
3281debfc3dSmrg     _Sp_counted_base<_S_single>::_M_weak_release() noexcept
3291debfc3dSmrg     {
3301debfc3dSmrg       if (--_M_weak_count == 0)
3311debfc3dSmrg         _M_destroy();
3321debfc3dSmrg     }
3331debfc3dSmrg 
3341debfc3dSmrg   template<>
3351debfc3dSmrg     inline long
3361debfc3dSmrg     _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept
3371debfc3dSmrg     { return _M_use_count; }
3381debfc3dSmrg 
3391debfc3dSmrg 
3401debfc3dSmrg   // Forward declarations.
3411debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
3421debfc3dSmrg     class __shared_ptr;
3431debfc3dSmrg 
3441debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
3451debfc3dSmrg     class __weak_ptr;
3461debfc3dSmrg 
3471debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
3481debfc3dSmrg     class __enable_shared_from_this;
3491debfc3dSmrg 
3501debfc3dSmrg   template<typename _Tp>
3511debfc3dSmrg     class shared_ptr;
3521debfc3dSmrg 
3531debfc3dSmrg   template<typename _Tp>
3541debfc3dSmrg     class weak_ptr;
3551debfc3dSmrg 
3561debfc3dSmrg   template<typename _Tp>
3571debfc3dSmrg     struct owner_less;
3581debfc3dSmrg 
3591debfc3dSmrg   template<typename _Tp>
3601debfc3dSmrg     class enable_shared_from_this;
3611debfc3dSmrg 
3621debfc3dSmrg   template<_Lock_policy _Lp = __default_lock_policy>
3631debfc3dSmrg     class __weak_count;
3641debfc3dSmrg 
3651debfc3dSmrg   template<_Lock_policy _Lp = __default_lock_policy>
3661debfc3dSmrg     class __shared_count;
3671debfc3dSmrg 
3681debfc3dSmrg 
3691debfc3dSmrg   // Counted ptr with no deleter or allocator support
3701debfc3dSmrg   template<typename _Ptr, _Lock_policy _Lp>
3711debfc3dSmrg     class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
3721debfc3dSmrg     {
3731debfc3dSmrg     public:
3741debfc3dSmrg       explicit
3751debfc3dSmrg       _Sp_counted_ptr(_Ptr __p) noexcept
3761debfc3dSmrg       : _M_ptr(__p) { }
3771debfc3dSmrg 
3781debfc3dSmrg       virtual void
3791debfc3dSmrg       _M_dispose() noexcept
3801debfc3dSmrg       { delete _M_ptr; }
3811debfc3dSmrg 
3821debfc3dSmrg       virtual void
3831debfc3dSmrg       _M_destroy() noexcept
3841debfc3dSmrg       { delete this; }
3851debfc3dSmrg 
3861debfc3dSmrg       virtual void*
3871debfc3dSmrg       _M_get_deleter(const std::type_info&) noexcept
3881debfc3dSmrg       { return nullptr; }
3891debfc3dSmrg 
3901debfc3dSmrg       _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
3911debfc3dSmrg       _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
3921debfc3dSmrg 
3931debfc3dSmrg     private:
3941debfc3dSmrg       _Ptr             _M_ptr;
3951debfc3dSmrg     };
3961debfc3dSmrg 
3971debfc3dSmrg   template<>
3981debfc3dSmrg     inline void
3991debfc3dSmrg     _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { }
4001debfc3dSmrg 
4011debfc3dSmrg   template<>
4021debfc3dSmrg     inline void
4031debfc3dSmrg     _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { }
4041debfc3dSmrg 
4051debfc3dSmrg   template<>
4061debfc3dSmrg     inline void
4071debfc3dSmrg     _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { }
4081debfc3dSmrg 
4091debfc3dSmrg   template<int _Nm, typename _Tp,
4101debfc3dSmrg 	   bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
4111debfc3dSmrg     struct _Sp_ebo_helper;
4121debfc3dSmrg 
4131debfc3dSmrg   /// Specialization using EBO.
4141debfc3dSmrg   template<int _Nm, typename _Tp>
4151debfc3dSmrg     struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp
4161debfc3dSmrg     {
4171debfc3dSmrg       explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { }
4181debfc3dSmrg       explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { }
4191debfc3dSmrg 
4201debfc3dSmrg       static _Tp&
4211debfc3dSmrg       _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); }
4221debfc3dSmrg     };
4231debfc3dSmrg 
4241debfc3dSmrg   /// Specialization not using EBO.
4251debfc3dSmrg   template<int _Nm, typename _Tp>
4261debfc3dSmrg     struct _Sp_ebo_helper<_Nm, _Tp, false>
4271debfc3dSmrg     {
4281debfc3dSmrg       explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { }
4291debfc3dSmrg       explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(std::move(__tp)) { }
4301debfc3dSmrg 
4311debfc3dSmrg       static _Tp&
4321debfc3dSmrg       _S_get(_Sp_ebo_helper& __eboh)
4331debfc3dSmrg       { return __eboh._M_tp; }
4341debfc3dSmrg 
4351debfc3dSmrg     private:
4361debfc3dSmrg       _Tp _M_tp;
4371debfc3dSmrg     };
4381debfc3dSmrg 
4391debfc3dSmrg   // Support for custom deleter and/or allocator
4401debfc3dSmrg   template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
4411debfc3dSmrg     class _Sp_counted_deleter final : public _Sp_counted_base<_Lp>
4421debfc3dSmrg     {
4431debfc3dSmrg       class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc>
4441debfc3dSmrg       {
4451debfc3dSmrg 	typedef _Sp_ebo_helper<0, _Deleter>	_Del_base;
4461debfc3dSmrg 	typedef _Sp_ebo_helper<1, _Alloc>	_Alloc_base;
4471debfc3dSmrg 
4481debfc3dSmrg       public:
4491debfc3dSmrg 	_Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
4501debfc3dSmrg 	: _M_ptr(__p), _Del_base(std::move(__d)), _Alloc_base(__a)
4511debfc3dSmrg 	{ }
4521debfc3dSmrg 
4531debfc3dSmrg 	_Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); }
4541debfc3dSmrg 	_Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); }
4551debfc3dSmrg 
4561debfc3dSmrg 	_Ptr _M_ptr;
4571debfc3dSmrg       };
4581debfc3dSmrg 
4591debfc3dSmrg     public:
4601debfc3dSmrg       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>;
4611debfc3dSmrg 
4621debfc3dSmrg       // __d(__p) must not throw.
4631debfc3dSmrg       _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
4641debfc3dSmrg       : _M_impl(__p, std::move(__d), _Alloc()) { }
4651debfc3dSmrg 
4661debfc3dSmrg       // __d(__p) must not throw.
4671debfc3dSmrg       _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
4681debfc3dSmrg       : _M_impl(__p, std::move(__d), __a) { }
4691debfc3dSmrg 
4701debfc3dSmrg       ~_Sp_counted_deleter() noexcept { }
4711debfc3dSmrg 
4721debfc3dSmrg       virtual void
4731debfc3dSmrg       _M_dispose() noexcept
4741debfc3dSmrg       { _M_impl._M_del()(_M_impl._M_ptr); }
4751debfc3dSmrg 
4761debfc3dSmrg       virtual void
4771debfc3dSmrg       _M_destroy() noexcept
4781debfc3dSmrg       {
4791debfc3dSmrg 	__allocator_type __a(_M_impl._M_alloc());
4801debfc3dSmrg 	__allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
4811debfc3dSmrg 	this->~_Sp_counted_deleter();
4821debfc3dSmrg       }
4831debfc3dSmrg 
4841debfc3dSmrg       virtual void*
4851debfc3dSmrg       _M_get_deleter(const std::type_info& __ti) noexcept
4861debfc3dSmrg       {
4871debfc3dSmrg #if __cpp_rtti
4881debfc3dSmrg 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
4891debfc3dSmrg 	// 2400. shared_ptr's get_deleter() should use addressof()
4901debfc3dSmrg         return __ti == typeid(_Deleter)
4911debfc3dSmrg 	  ? std::__addressof(_M_impl._M_del())
4921debfc3dSmrg 	  : nullptr;
4931debfc3dSmrg #else
4941debfc3dSmrg         return nullptr;
4951debfc3dSmrg #endif
4961debfc3dSmrg       }
4971debfc3dSmrg 
4981debfc3dSmrg     private:
4991debfc3dSmrg       _Impl _M_impl;
5001debfc3dSmrg     };
5011debfc3dSmrg 
5021debfc3dSmrg   // helpers for make_shared / allocate_shared
5031debfc3dSmrg 
504a2dc1f3fSmrg   struct _Sp_make_shared_tag
505a2dc1f3fSmrg   {
506a2dc1f3fSmrg   private:
507a2dc1f3fSmrg     template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
508a2dc1f3fSmrg       friend class _Sp_counted_ptr_inplace;
509a2dc1f3fSmrg 
510a2dc1f3fSmrg     static const type_info&
511a2dc1f3fSmrg     _S_ti() noexcept _GLIBCXX_VISIBILITY(default)
512a2dc1f3fSmrg     {
513a2dc1f3fSmrg       alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { };
514a2dc1f3fSmrg       return reinterpret_cast<const type_info&>(__tag);
515a2dc1f3fSmrg     }
516c0a68be4Smrg 
517c0a68be4Smrg     static bool _S_eq(const type_info&) noexcept;
518a2dc1f3fSmrg   };
519a2dc1f3fSmrg 
520a2dc1f3fSmrg   template<typename _Alloc>
521a2dc1f3fSmrg     struct _Sp_alloc_shared_tag
522a2dc1f3fSmrg     {
523a2dc1f3fSmrg       const _Alloc& _M_a;
524a2dc1f3fSmrg     };
5251debfc3dSmrg 
5261debfc3dSmrg   template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
5271debfc3dSmrg     class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
5281debfc3dSmrg     {
5291debfc3dSmrg       class _Impl : _Sp_ebo_helper<0, _Alloc>
5301debfc3dSmrg       {
5311debfc3dSmrg 	typedef _Sp_ebo_helper<0, _Alloc>	_A_base;
5321debfc3dSmrg 
5331debfc3dSmrg       public:
5341debfc3dSmrg 	explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { }
5351debfc3dSmrg 
5361debfc3dSmrg 	_Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); }
5371debfc3dSmrg 
5381debfc3dSmrg 	__gnu_cxx::__aligned_buffer<_Tp> _M_storage;
5391debfc3dSmrg       };
5401debfc3dSmrg 
5411debfc3dSmrg     public:
5421debfc3dSmrg       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
5431debfc3dSmrg 
544c0a68be4Smrg       // Alloc parameter is not a reference so doesn't alias anything in __args
5451debfc3dSmrg       template<typename... _Args>
5461debfc3dSmrg 	_Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
5471debfc3dSmrg 	: _M_impl(__a)
5481debfc3dSmrg 	{
5491debfc3dSmrg 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
5501debfc3dSmrg 	  // 2070.  allocate_shared should use allocator_traits<A>::construct
5511debfc3dSmrg 	  allocator_traits<_Alloc>::construct(__a, _M_ptr(),
5521debfc3dSmrg 	      std::forward<_Args>(__args)...); // might throw
5531debfc3dSmrg 	}
5541debfc3dSmrg 
5551debfc3dSmrg       ~_Sp_counted_ptr_inplace() noexcept { }
5561debfc3dSmrg 
5571debfc3dSmrg       virtual void
5581debfc3dSmrg       _M_dispose() noexcept
5591debfc3dSmrg       {
5601debfc3dSmrg 	allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
5611debfc3dSmrg       }
5621debfc3dSmrg 
5631debfc3dSmrg       // Override because the allocator needs to know the dynamic type
5641debfc3dSmrg       virtual void
5651debfc3dSmrg       _M_destroy() noexcept
5661debfc3dSmrg       {
5671debfc3dSmrg 	__allocator_type __a(_M_impl._M_alloc());
5681debfc3dSmrg 	__allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
5691debfc3dSmrg 	this->~_Sp_counted_ptr_inplace();
5701debfc3dSmrg       }
5711debfc3dSmrg 
572a2dc1f3fSmrg     private:
573a2dc1f3fSmrg       friend class __shared_count<_Lp>; // To be able to call _M_ptr().
574a2dc1f3fSmrg 
575a2dc1f3fSmrg       // No longer used, but code compiled against old libstdc++ headers
576a2dc1f3fSmrg       // might still call it from __shared_ptr ctor to get the pointer out.
5771debfc3dSmrg       virtual void*
578a2dc1f3fSmrg       _M_get_deleter(const std::type_info& __ti) noexcept override
5791debfc3dSmrg       {
580c0a68be4Smrg 	auto __ptr = const_cast<typename remove_cv<_Tp>::type*>(_M_ptr());
581a2dc1f3fSmrg 	// Check for the fake type_info first, so we don't try to access it
582c0a68be4Smrg 	// as a real type_info object. Otherwise, check if it's the real
583c0a68be4Smrg 	// type_info for this class. With RTTI enabled we can check directly,
584c0a68be4Smrg 	// or call a library function to do it.
585c0a68be4Smrg 	if (&__ti == &_Sp_make_shared_tag::_S_ti()
586c0a68be4Smrg 	    ||
587a2dc1f3fSmrg #if __cpp_rtti
588c0a68be4Smrg 	    __ti == typeid(_Sp_make_shared_tag)
589a2dc1f3fSmrg #else
590c0a68be4Smrg 	    _Sp_make_shared_tag::_S_eq(__ti)
5911debfc3dSmrg #endif
592c0a68be4Smrg 	   )
593c0a68be4Smrg 	  return __ptr;
5941debfc3dSmrg 	return nullptr;
5951debfc3dSmrg       }
5961debfc3dSmrg 
5971debfc3dSmrg       _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
5981debfc3dSmrg 
5991debfc3dSmrg       _Impl _M_impl;
6001debfc3dSmrg     };
6011debfc3dSmrg 
6021debfc3dSmrg   // The default deleter for shared_ptr<T[]> and shared_ptr<T[N]>.
6031debfc3dSmrg   struct __sp_array_delete
6041debfc3dSmrg   {
6051debfc3dSmrg     template<typename _Yp>
6061debfc3dSmrg       void operator()(_Yp* __p) const { delete[] __p; }
6071debfc3dSmrg   };
6081debfc3dSmrg 
6091debfc3dSmrg   template<_Lock_policy _Lp>
6101debfc3dSmrg     class __shared_count
6111debfc3dSmrg     {
612a2dc1f3fSmrg       template<typename _Tp>
613a2dc1f3fSmrg 	struct __not_alloc_shared_tag { using type = void; };
614a2dc1f3fSmrg 
615a2dc1f3fSmrg       template<typename _Tp>
616a2dc1f3fSmrg 	struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { };
617a2dc1f3fSmrg 
6181debfc3dSmrg     public:
6191debfc3dSmrg       constexpr __shared_count() noexcept : _M_pi(0)
6201debfc3dSmrg       { }
6211debfc3dSmrg 
6221debfc3dSmrg       template<typename _Ptr>
6231debfc3dSmrg         explicit
6241debfc3dSmrg 	__shared_count(_Ptr __p) : _M_pi(0)
6251debfc3dSmrg 	{
6261debfc3dSmrg 	  __try
6271debfc3dSmrg 	    {
6281debfc3dSmrg 	      _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
6291debfc3dSmrg 	    }
6301debfc3dSmrg 	  __catch(...)
6311debfc3dSmrg 	    {
6321debfc3dSmrg 	      delete __p;
6331debfc3dSmrg 	      __throw_exception_again;
6341debfc3dSmrg 	    }
6351debfc3dSmrg 	}
6361debfc3dSmrg 
6371debfc3dSmrg       template<typename _Ptr>
6381debfc3dSmrg 	__shared_count(_Ptr __p, /* is_array = */ false_type)
6391debfc3dSmrg 	: __shared_count(__p)
6401debfc3dSmrg 	{ }
6411debfc3dSmrg 
6421debfc3dSmrg       template<typename _Ptr>
6431debfc3dSmrg 	__shared_count(_Ptr __p, /* is_array = */ true_type)
6441debfc3dSmrg 	: __shared_count(__p, __sp_array_delete{}, allocator<void>())
6451debfc3dSmrg 	{ }
6461debfc3dSmrg 
647a2dc1f3fSmrg       template<typename _Ptr, typename _Deleter,
648a2dc1f3fSmrg 	       typename = typename __not_alloc_shared_tag<_Deleter>::type>
6491debfc3dSmrg 	__shared_count(_Ptr __p, _Deleter __d)
6501debfc3dSmrg 	: __shared_count(__p, std::move(__d), allocator<void>())
6511debfc3dSmrg 	{ }
6521debfc3dSmrg 
653a2dc1f3fSmrg       template<typename _Ptr, typename _Deleter, typename _Alloc,
654a2dc1f3fSmrg 	       typename = typename __not_alloc_shared_tag<_Deleter>::type>
6551debfc3dSmrg 	__shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
6561debfc3dSmrg 	{
6571debfc3dSmrg 	  typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
6581debfc3dSmrg 	  __try
6591debfc3dSmrg 	    {
6601debfc3dSmrg 	      typename _Sp_cd_type::__allocator_type __a2(__a);
6611debfc3dSmrg 	      auto __guard = std::__allocate_guarded(__a2);
6621debfc3dSmrg 	      _Sp_cd_type* __mem = __guard.get();
6631debfc3dSmrg 	      ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a));
6641debfc3dSmrg 	      _M_pi = __mem;
6651debfc3dSmrg 	      __guard = nullptr;
6661debfc3dSmrg 	    }
6671debfc3dSmrg 	  __catch(...)
6681debfc3dSmrg 	    {
6691debfc3dSmrg 	      __d(__p); // Call _Deleter on __p.
6701debfc3dSmrg 	      __throw_exception_again;
6711debfc3dSmrg 	    }
6721debfc3dSmrg 	}
6731debfc3dSmrg 
6741debfc3dSmrg       template<typename _Tp, typename _Alloc, typename... _Args>
675a2dc1f3fSmrg 	__shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a,
6761debfc3dSmrg 		       _Args&&... __args)
6771debfc3dSmrg 	{
6781debfc3dSmrg 	  typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
679a2dc1f3fSmrg 	  typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
6801debfc3dSmrg 	  auto __guard = std::__allocate_guarded(__a2);
6811debfc3dSmrg 	  _Sp_cp_type* __mem = __guard.get();
682a2dc1f3fSmrg 	  auto __pi = ::new (__mem)
683a2dc1f3fSmrg 	    _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
6841debfc3dSmrg 	  __guard = nullptr;
685a2dc1f3fSmrg 	  _M_pi = __pi;
686a2dc1f3fSmrg 	  __p = __pi->_M_ptr();
6871debfc3dSmrg 	}
6881debfc3dSmrg 
6891debfc3dSmrg #if _GLIBCXX_USE_DEPRECATED
690a2dc1f3fSmrg #pragma GCC diagnostic push
691a2dc1f3fSmrg #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
6921debfc3dSmrg       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
6931debfc3dSmrg       template<typename _Tp>
6941debfc3dSmrg         explicit
6951debfc3dSmrg 	__shared_count(std::auto_ptr<_Tp>&& __r);
696a2dc1f3fSmrg #pragma GCC diagnostic pop
6971debfc3dSmrg #endif
6981debfc3dSmrg 
6991debfc3dSmrg       // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
7001debfc3dSmrg       template<typename _Tp, typename _Del>
7011debfc3dSmrg         explicit
7021debfc3dSmrg 	__shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
7031debfc3dSmrg 	{
7041debfc3dSmrg 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
7051debfc3dSmrg 	  // 2415. Inconsistency between unique_ptr and shared_ptr
7061debfc3dSmrg 	  if (__r.get() == nullptr)
7071debfc3dSmrg 	    return;
7081debfc3dSmrg 
7091debfc3dSmrg 	  using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
7101debfc3dSmrg 	  using _Del2 = typename conditional<is_reference<_Del>::value,
7111debfc3dSmrg 	      reference_wrapper<typename remove_reference<_Del>::type>,
7121debfc3dSmrg 	      _Del>::type;
7131debfc3dSmrg 	  using _Sp_cd_type
7141debfc3dSmrg 	    = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
7151debfc3dSmrg 	  using _Alloc = allocator<_Sp_cd_type>;
7161debfc3dSmrg 	  using _Alloc_traits = allocator_traits<_Alloc>;
7171debfc3dSmrg 	  _Alloc __a;
7181debfc3dSmrg 	  _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
7198feb0f0bSmrg 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
7208feb0f0bSmrg 	  // 3548. shared_ptr construction from unique_ptr should move
7218feb0f0bSmrg 	  // (not copy) the deleter
7221debfc3dSmrg 	  _Alloc_traits::construct(__a, __mem, __r.release(),
7238feb0f0bSmrg 				   std::forward<_Del>(__r.get_deleter()));
7241debfc3dSmrg 	  _M_pi = __mem;
7251debfc3dSmrg 	}
7261debfc3dSmrg 
7271debfc3dSmrg       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
7281debfc3dSmrg       explicit __shared_count(const __weak_count<_Lp>& __r);
7291debfc3dSmrg 
7301debfc3dSmrg       // Does not throw if __r._M_get_use_count() == 0, caller must check.
7311debfc3dSmrg       explicit __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t);
7321debfc3dSmrg 
7331debfc3dSmrg       ~__shared_count() noexcept
7341debfc3dSmrg       {
7351debfc3dSmrg 	if (_M_pi != nullptr)
7361debfc3dSmrg 	  _M_pi->_M_release();
7371debfc3dSmrg       }
7381debfc3dSmrg 
7391debfc3dSmrg       __shared_count(const __shared_count& __r) noexcept
7401debfc3dSmrg       : _M_pi(__r._M_pi)
7411debfc3dSmrg       {
7421debfc3dSmrg 	if (_M_pi != 0)
7431debfc3dSmrg 	  _M_pi->_M_add_ref_copy();
7441debfc3dSmrg       }
7451debfc3dSmrg 
7461debfc3dSmrg       __shared_count&
7471debfc3dSmrg       operator=(const __shared_count& __r) noexcept
7481debfc3dSmrg       {
7491debfc3dSmrg 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
7501debfc3dSmrg 	if (__tmp != _M_pi)
7511debfc3dSmrg 	  {
7521debfc3dSmrg 	    if (__tmp != 0)
7531debfc3dSmrg 	      __tmp->_M_add_ref_copy();
7541debfc3dSmrg 	    if (_M_pi != 0)
7551debfc3dSmrg 	      _M_pi->_M_release();
7561debfc3dSmrg 	    _M_pi = __tmp;
7571debfc3dSmrg 	  }
7581debfc3dSmrg 	return *this;
7591debfc3dSmrg       }
7601debfc3dSmrg 
7611debfc3dSmrg       void
7621debfc3dSmrg       _M_swap(__shared_count& __r) noexcept
7631debfc3dSmrg       {
7641debfc3dSmrg 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
7651debfc3dSmrg 	__r._M_pi = _M_pi;
7661debfc3dSmrg 	_M_pi = __tmp;
7671debfc3dSmrg       }
7681debfc3dSmrg 
7691debfc3dSmrg       long
7701debfc3dSmrg       _M_get_use_count() const noexcept
7711debfc3dSmrg       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
7721debfc3dSmrg 
7731debfc3dSmrg       bool
7741debfc3dSmrg       _M_unique() const noexcept
7751debfc3dSmrg       { return this->_M_get_use_count() == 1; }
7761debfc3dSmrg 
7771debfc3dSmrg       void*
7781debfc3dSmrg       _M_get_deleter(const std::type_info& __ti) const noexcept
7791debfc3dSmrg       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; }
7801debfc3dSmrg 
7811debfc3dSmrg       bool
7821debfc3dSmrg       _M_less(const __shared_count& __rhs) const noexcept
7831debfc3dSmrg       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
7841debfc3dSmrg 
7851debfc3dSmrg       bool
7861debfc3dSmrg       _M_less(const __weak_count<_Lp>& __rhs) const noexcept
7871debfc3dSmrg       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
7881debfc3dSmrg 
7891debfc3dSmrg       // Friend function injected into enclosing namespace and found by ADL
7901debfc3dSmrg       friend inline bool
7911debfc3dSmrg       operator==(const __shared_count& __a, const __shared_count& __b) noexcept
7921debfc3dSmrg       { return __a._M_pi == __b._M_pi; }
7931debfc3dSmrg 
7941debfc3dSmrg     private:
7951debfc3dSmrg       friend class __weak_count<_Lp>;
7961debfc3dSmrg 
7971debfc3dSmrg       _Sp_counted_base<_Lp>*  _M_pi;
7981debfc3dSmrg     };
7991debfc3dSmrg 
8001debfc3dSmrg 
8011debfc3dSmrg   template<_Lock_policy _Lp>
8021debfc3dSmrg     class __weak_count
8031debfc3dSmrg     {
8041debfc3dSmrg     public:
8051debfc3dSmrg       constexpr __weak_count() noexcept : _M_pi(nullptr)
8061debfc3dSmrg       { }
8071debfc3dSmrg 
8081debfc3dSmrg       __weak_count(const __shared_count<_Lp>& __r) noexcept
8091debfc3dSmrg       : _M_pi(__r._M_pi)
8101debfc3dSmrg       {
8111debfc3dSmrg 	if (_M_pi != nullptr)
8121debfc3dSmrg 	  _M_pi->_M_weak_add_ref();
8131debfc3dSmrg       }
8141debfc3dSmrg 
8151debfc3dSmrg       __weak_count(const __weak_count& __r) noexcept
8161debfc3dSmrg       : _M_pi(__r._M_pi)
8171debfc3dSmrg       {
8181debfc3dSmrg 	if (_M_pi != nullptr)
8191debfc3dSmrg 	  _M_pi->_M_weak_add_ref();
8201debfc3dSmrg       }
8211debfc3dSmrg 
8221debfc3dSmrg       __weak_count(__weak_count&& __r) noexcept
8231debfc3dSmrg       : _M_pi(__r._M_pi)
8241debfc3dSmrg       { __r._M_pi = nullptr; }
8251debfc3dSmrg 
8261debfc3dSmrg       ~__weak_count() noexcept
8271debfc3dSmrg       {
8281debfc3dSmrg 	if (_M_pi != nullptr)
8291debfc3dSmrg 	  _M_pi->_M_weak_release();
8301debfc3dSmrg       }
8311debfc3dSmrg 
8321debfc3dSmrg       __weak_count&
8331debfc3dSmrg       operator=(const __shared_count<_Lp>& __r) noexcept
8341debfc3dSmrg       {
8351debfc3dSmrg 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
8361debfc3dSmrg 	if (__tmp != nullptr)
8371debfc3dSmrg 	  __tmp->_M_weak_add_ref();
8381debfc3dSmrg 	if (_M_pi != nullptr)
8391debfc3dSmrg 	  _M_pi->_M_weak_release();
8401debfc3dSmrg 	_M_pi = __tmp;
8411debfc3dSmrg 	return *this;
8421debfc3dSmrg       }
8431debfc3dSmrg 
8441debfc3dSmrg       __weak_count&
8451debfc3dSmrg       operator=(const __weak_count& __r) noexcept
8461debfc3dSmrg       {
8471debfc3dSmrg 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
8481debfc3dSmrg 	if (__tmp != nullptr)
8491debfc3dSmrg 	  __tmp->_M_weak_add_ref();
8501debfc3dSmrg 	if (_M_pi != nullptr)
8511debfc3dSmrg 	  _M_pi->_M_weak_release();
8521debfc3dSmrg 	_M_pi = __tmp;
8531debfc3dSmrg 	return *this;
8541debfc3dSmrg       }
8551debfc3dSmrg 
8561debfc3dSmrg       __weak_count&
8571debfc3dSmrg       operator=(__weak_count&& __r) noexcept
8581debfc3dSmrg       {
8591debfc3dSmrg 	if (_M_pi != nullptr)
8601debfc3dSmrg 	  _M_pi->_M_weak_release();
8611debfc3dSmrg 	_M_pi = __r._M_pi;
8621debfc3dSmrg         __r._M_pi = nullptr;
8631debfc3dSmrg 	return *this;
8641debfc3dSmrg       }
8651debfc3dSmrg 
8661debfc3dSmrg       void
8671debfc3dSmrg       _M_swap(__weak_count& __r) noexcept
8681debfc3dSmrg       {
8691debfc3dSmrg 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
8701debfc3dSmrg 	__r._M_pi = _M_pi;
8711debfc3dSmrg 	_M_pi = __tmp;
8721debfc3dSmrg       }
8731debfc3dSmrg 
8741debfc3dSmrg       long
8751debfc3dSmrg       _M_get_use_count() const noexcept
8761debfc3dSmrg       { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
8771debfc3dSmrg 
8781debfc3dSmrg       bool
8791debfc3dSmrg       _M_less(const __weak_count& __rhs) const noexcept
8801debfc3dSmrg       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
8811debfc3dSmrg 
8821debfc3dSmrg       bool
8831debfc3dSmrg       _M_less(const __shared_count<_Lp>& __rhs) const noexcept
8841debfc3dSmrg       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
8851debfc3dSmrg 
8861debfc3dSmrg       // Friend function injected into enclosing namespace and found by ADL
8871debfc3dSmrg       friend inline bool
8881debfc3dSmrg       operator==(const __weak_count& __a, const __weak_count& __b) noexcept
8891debfc3dSmrg       { return __a._M_pi == __b._M_pi; }
8901debfc3dSmrg 
8911debfc3dSmrg     private:
8921debfc3dSmrg       friend class __shared_count<_Lp>;
8931debfc3dSmrg 
8941debfc3dSmrg       _Sp_counted_base<_Lp>*  _M_pi;
8951debfc3dSmrg     };
8961debfc3dSmrg 
8971debfc3dSmrg   // Now that __weak_count is defined we can define this constructor:
8981debfc3dSmrg   template<_Lock_policy _Lp>
8991debfc3dSmrg     inline
9001debfc3dSmrg     __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
9011debfc3dSmrg     : _M_pi(__r._M_pi)
9021debfc3dSmrg     {
9031debfc3dSmrg       if (_M_pi != nullptr)
9041debfc3dSmrg 	_M_pi->_M_add_ref_lock();
9051debfc3dSmrg       else
9061debfc3dSmrg 	__throw_bad_weak_ptr();
9071debfc3dSmrg     }
9081debfc3dSmrg 
9091debfc3dSmrg   // Now that __weak_count is defined we can define this constructor:
9101debfc3dSmrg   template<_Lock_policy _Lp>
9111debfc3dSmrg     inline
9121debfc3dSmrg     __shared_count<_Lp>::
9131debfc3dSmrg     __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t)
9141debfc3dSmrg     : _M_pi(__r._M_pi)
9151debfc3dSmrg     {
9161debfc3dSmrg       if (_M_pi != nullptr)
9171debfc3dSmrg 	if (!_M_pi->_M_add_ref_lock_nothrow())
9181debfc3dSmrg 	  _M_pi = nullptr;
9191debfc3dSmrg     }
9201debfc3dSmrg 
921c0a68be4Smrg #define __cpp_lib_shared_ptr_arrays 201611L
9221debfc3dSmrg 
9231debfc3dSmrg   // Helper traits for shared_ptr of array:
9241debfc3dSmrg 
9251debfc3dSmrg   // A pointer type Y* is said to be compatible with a pointer type T* when
9261debfc3dSmrg   // either Y* is convertible to T* or Y is U[N] and T is U cv [].
9271debfc3dSmrg   template<typename _Yp_ptr, typename _Tp_ptr>
9281debfc3dSmrg     struct __sp_compatible_with
9291debfc3dSmrg     : false_type
9301debfc3dSmrg     { };
9311debfc3dSmrg 
9321debfc3dSmrg   template<typename _Yp, typename _Tp>
9331debfc3dSmrg     struct __sp_compatible_with<_Yp*, _Tp*>
9341debfc3dSmrg     : is_convertible<_Yp*, _Tp*>::type
9351debfc3dSmrg     { };
9361debfc3dSmrg 
9371debfc3dSmrg   template<typename _Up, size_t _Nm>
9381debfc3dSmrg     struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]>
9391debfc3dSmrg     : true_type
9401debfc3dSmrg     { };
9411debfc3dSmrg 
9421debfc3dSmrg   template<typename _Up, size_t _Nm>
9431debfc3dSmrg     struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]>
9441debfc3dSmrg     : true_type
9451debfc3dSmrg     { };
9461debfc3dSmrg 
9471debfc3dSmrg   template<typename _Up, size_t _Nm>
9481debfc3dSmrg     struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]>
9491debfc3dSmrg     : true_type
9501debfc3dSmrg     { };
9511debfc3dSmrg 
9521debfc3dSmrg   template<typename _Up, size_t _Nm>
9531debfc3dSmrg     struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]>
9541debfc3dSmrg     : true_type
9551debfc3dSmrg     { };
9561debfc3dSmrg 
9571debfc3dSmrg   // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N].
9581debfc3dSmrg   template<typename _Up, size_t _Nm, typename _Yp, typename = void>
9591debfc3dSmrg     struct __sp_is_constructible_arrN
9601debfc3dSmrg     : false_type
9611debfc3dSmrg     { };
9621debfc3dSmrg 
9631debfc3dSmrg   template<typename _Up, size_t _Nm, typename _Yp>
9641debfc3dSmrg     struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
9651debfc3dSmrg     : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
9661debfc3dSmrg     { };
9671debfc3dSmrg 
9681debfc3dSmrg   // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[].
9691debfc3dSmrg   template<typename _Up, typename _Yp, typename = void>
9701debfc3dSmrg     struct __sp_is_constructible_arr
9711debfc3dSmrg     : false_type
9721debfc3dSmrg     { };
9731debfc3dSmrg 
9741debfc3dSmrg   template<typename _Up, typename _Yp>
9751debfc3dSmrg     struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
9761debfc3dSmrg     : is_convertible<_Yp(*)[], _Up(*)[]>::type
9771debfc3dSmrg     { };
9781debfc3dSmrg 
9791debfc3dSmrg   // Trait to check if shared_ptr<T> can be constructed from Y*.
9801debfc3dSmrg   template<typename _Tp, typename _Yp>
9811debfc3dSmrg     struct __sp_is_constructible;
9821debfc3dSmrg 
9831debfc3dSmrg   // When T is U[N], Y(*)[N] shall be convertible to T*;
9841debfc3dSmrg   template<typename _Up, size_t _Nm, typename _Yp>
9851debfc3dSmrg     struct __sp_is_constructible<_Up[_Nm], _Yp>
9861debfc3dSmrg     : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
9871debfc3dSmrg     { };
9881debfc3dSmrg 
9891debfc3dSmrg   // when T is U[], Y(*)[] shall be convertible to T*;
9901debfc3dSmrg   template<typename _Up, typename _Yp>
9911debfc3dSmrg     struct __sp_is_constructible<_Up[], _Yp>
9921debfc3dSmrg     : __sp_is_constructible_arr<_Up, _Yp>::type
9931debfc3dSmrg     { };
9941debfc3dSmrg 
9951debfc3dSmrg   // otherwise, Y* shall be convertible to T*.
9961debfc3dSmrg   template<typename _Tp, typename _Yp>
9971debfc3dSmrg     struct __sp_is_constructible
9981debfc3dSmrg     : is_convertible<_Yp*, _Tp*>::type
9991debfc3dSmrg     { };
10001debfc3dSmrg 
10011debfc3dSmrg 
10021debfc3dSmrg   // Define operator* and operator-> for shared_ptr<T>.
10031debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp,
10041debfc3dSmrg 	   bool = is_array<_Tp>::value, bool = is_void<_Tp>::value>
10051debfc3dSmrg     class __shared_ptr_access
10061debfc3dSmrg     {
10071debfc3dSmrg     public:
10081debfc3dSmrg       using element_type = _Tp;
10091debfc3dSmrg 
10101debfc3dSmrg       element_type&
10111debfc3dSmrg       operator*() const noexcept
10121debfc3dSmrg       {
10131debfc3dSmrg 	__glibcxx_assert(_M_get() != nullptr);
10141debfc3dSmrg 	return *_M_get();
10151debfc3dSmrg       }
10161debfc3dSmrg 
10171debfc3dSmrg       element_type*
10181debfc3dSmrg       operator->() const noexcept
10191debfc3dSmrg       {
10201debfc3dSmrg 	_GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
10211debfc3dSmrg 	return _M_get();
10221debfc3dSmrg       }
10231debfc3dSmrg 
10241debfc3dSmrg     private:
10251debfc3dSmrg       element_type*
10261debfc3dSmrg       _M_get() const noexcept
10271debfc3dSmrg       { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
10281debfc3dSmrg     };
10291debfc3dSmrg 
10301debfc3dSmrg   // Define operator-> for shared_ptr<cv void>.
10311debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
10321debfc3dSmrg     class __shared_ptr_access<_Tp, _Lp, false, true>
10331debfc3dSmrg     {
10341debfc3dSmrg     public:
10351debfc3dSmrg       using element_type = _Tp;
10361debfc3dSmrg 
10371debfc3dSmrg       element_type*
10381debfc3dSmrg       operator->() const noexcept
10391debfc3dSmrg       {
10401debfc3dSmrg 	auto __ptr = static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get();
10411debfc3dSmrg 	_GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr);
10421debfc3dSmrg 	return __ptr;
10431debfc3dSmrg       }
10441debfc3dSmrg     };
10451debfc3dSmrg 
10461debfc3dSmrg   // Define operator[] for shared_ptr<T[]> and shared_ptr<T[N]>.
10471debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
10481debfc3dSmrg     class __shared_ptr_access<_Tp, _Lp, true, false>
10491debfc3dSmrg     {
10501debfc3dSmrg     public:
10511debfc3dSmrg       using element_type = typename remove_extent<_Tp>::type;
10521debfc3dSmrg 
10531debfc3dSmrg #if __cplusplus <= 201402L
10541debfc3dSmrg       [[__deprecated__("shared_ptr<T[]>::operator* is absent from C++17")]]
10551debfc3dSmrg       element_type&
10561debfc3dSmrg       operator*() const noexcept
10571debfc3dSmrg       {
10581debfc3dSmrg 	__glibcxx_assert(_M_get() != nullptr);
10591debfc3dSmrg 	return *_M_get();
10601debfc3dSmrg       }
10611debfc3dSmrg 
10621debfc3dSmrg       [[__deprecated__("shared_ptr<T[]>::operator-> is absent from C++17")]]
10631debfc3dSmrg       element_type*
10641debfc3dSmrg       operator->() const noexcept
10651debfc3dSmrg       {
10661debfc3dSmrg 	_GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
10671debfc3dSmrg 	return _M_get();
10681debfc3dSmrg       }
10691debfc3dSmrg #endif
10701debfc3dSmrg 
10711debfc3dSmrg       element_type&
10721debfc3dSmrg       operator[](ptrdiff_t __i) const
10731debfc3dSmrg       {
10741debfc3dSmrg 	__glibcxx_assert(_M_get() != nullptr);
10751debfc3dSmrg 	__glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value);
10761debfc3dSmrg 	return _M_get()[__i];
10771debfc3dSmrg       }
10781debfc3dSmrg 
10791debfc3dSmrg     private:
10801debfc3dSmrg       element_type*
10811debfc3dSmrg       _M_get() const noexcept
10821debfc3dSmrg       { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
10831debfc3dSmrg     };
10841debfc3dSmrg 
10851debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
10861debfc3dSmrg     class __shared_ptr
10871debfc3dSmrg     : public __shared_ptr_access<_Tp, _Lp>
10881debfc3dSmrg     {
10891debfc3dSmrg     public:
10901debfc3dSmrg       using element_type = typename remove_extent<_Tp>::type;
10911debfc3dSmrg 
10921debfc3dSmrg     private:
10931debfc3dSmrg       // Constraint for taking ownership of a pointer of type _Yp*:
10941debfc3dSmrg       template<typename _Yp>
10951debfc3dSmrg 	using _SafeConv
10961debfc3dSmrg 	  = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type;
10971debfc3dSmrg 
10981debfc3dSmrg       // Constraint for construction from shared_ptr and weak_ptr:
10991debfc3dSmrg       template<typename _Yp, typename _Res = void>
11001debfc3dSmrg 	using _Compatible = typename
11011debfc3dSmrg 	  enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
11021debfc3dSmrg 
11031debfc3dSmrg       // Constraint for assignment from shared_ptr and weak_ptr:
11041debfc3dSmrg       template<typename _Yp>
11051debfc3dSmrg 	using _Assignable = _Compatible<_Yp, __shared_ptr&>;
11061debfc3dSmrg 
11071debfc3dSmrg       // Constraint for construction from unique_ptr:
11081debfc3dSmrg       template<typename _Yp, typename _Del, typename _Res = void,
11091debfc3dSmrg 	       typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer>
11108feb0f0bSmrg 	using _UniqCompatible = __enable_if_t<__and_<
11118feb0f0bSmrg 	  __sp_compatible_with<_Yp*, _Tp*>,
11128feb0f0bSmrg 	  is_convertible<_Ptr, element_type*>,
11138feb0f0bSmrg 	  is_move_constructible<_Del>
11148feb0f0bSmrg 	  >::value, _Res>;
11151debfc3dSmrg 
11161debfc3dSmrg       // Constraint for assignment from unique_ptr:
11171debfc3dSmrg       template<typename _Yp, typename _Del>
11181debfc3dSmrg 	using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>;
11191debfc3dSmrg 
11201debfc3dSmrg     public:
11211debfc3dSmrg 
11221debfc3dSmrg #if __cplusplus > 201402L
11231debfc3dSmrg       using weak_type = __weak_ptr<_Tp, _Lp>;
11241debfc3dSmrg #endif
11251debfc3dSmrg 
11261debfc3dSmrg       constexpr __shared_ptr() noexcept
11271debfc3dSmrg       : _M_ptr(0), _M_refcount()
11281debfc3dSmrg       { }
11291debfc3dSmrg 
11301debfc3dSmrg       template<typename _Yp, typename = _SafeConv<_Yp>>
11311debfc3dSmrg 	explicit
11321debfc3dSmrg 	__shared_ptr(_Yp* __p)
11331debfc3dSmrg 	: _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type())
11341debfc3dSmrg 	{
11351debfc3dSmrg 	  static_assert( !is_void<_Yp>::value, "incomplete type" );
11361debfc3dSmrg 	  static_assert( sizeof(_Yp) > 0, "incomplete type" );
11371debfc3dSmrg 	  _M_enable_shared_from_this_with(__p);
11381debfc3dSmrg 	}
11391debfc3dSmrg 
11401debfc3dSmrg       template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>>
11411debfc3dSmrg 	__shared_ptr(_Yp* __p, _Deleter __d)
11421debfc3dSmrg 	: _M_ptr(__p), _M_refcount(__p, std::move(__d))
11431debfc3dSmrg 	{
11441debfc3dSmrg 	  static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
11451debfc3dSmrg 	      "deleter expression d(p) is well-formed");
11461debfc3dSmrg 	  _M_enable_shared_from_this_with(__p);
11471debfc3dSmrg 	}
11481debfc3dSmrg 
11491debfc3dSmrg       template<typename _Yp, typename _Deleter, typename _Alloc,
11501debfc3dSmrg 	       typename = _SafeConv<_Yp>>
11511debfc3dSmrg 	__shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
11521debfc3dSmrg 	: _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a))
11531debfc3dSmrg 	{
11541debfc3dSmrg 	  static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
11551debfc3dSmrg 	      "deleter expression d(p) is well-formed");
11561debfc3dSmrg 	  _M_enable_shared_from_this_with(__p);
11571debfc3dSmrg 	}
11581debfc3dSmrg 
11591debfc3dSmrg       template<typename _Deleter>
11601debfc3dSmrg 	__shared_ptr(nullptr_t __p, _Deleter __d)
11611debfc3dSmrg 	: _M_ptr(0), _M_refcount(__p, std::move(__d))
11621debfc3dSmrg 	{ }
11631debfc3dSmrg 
11641debfc3dSmrg       template<typename _Deleter, typename _Alloc>
11651debfc3dSmrg         __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
11661debfc3dSmrg 	: _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a))
11671debfc3dSmrg 	{ }
11681debfc3dSmrg 
11698feb0f0bSmrg       // Aliasing constructor
11701debfc3dSmrg       template<typename _Yp>
11711debfc3dSmrg 	__shared_ptr(const __shared_ptr<_Yp, _Lp>& __r,
11721debfc3dSmrg 		     element_type* __p) noexcept
11731debfc3dSmrg 	: _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
11741debfc3dSmrg 	{ }
11751debfc3dSmrg 
11768feb0f0bSmrg       // Aliasing constructor
11778feb0f0bSmrg       template<typename _Yp>
11788feb0f0bSmrg 	__shared_ptr(__shared_ptr<_Yp, _Lp>&& __r,
11798feb0f0bSmrg 		     element_type* __p) noexcept
11808feb0f0bSmrg 	: _M_ptr(__p), _M_refcount()
11818feb0f0bSmrg 	{
11828feb0f0bSmrg 	  _M_refcount._M_swap(__r._M_refcount);
11838feb0f0bSmrg 	  __r._M_ptr = 0;
11848feb0f0bSmrg 	}
11858feb0f0bSmrg 
11861debfc3dSmrg       __shared_ptr(const __shared_ptr&) noexcept = default;
11871debfc3dSmrg       __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
11881debfc3dSmrg       ~__shared_ptr() = default;
11891debfc3dSmrg 
11901debfc3dSmrg       template<typename _Yp, typename = _Compatible<_Yp>>
11911debfc3dSmrg 	__shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
11921debfc3dSmrg 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
11931debfc3dSmrg 	{ }
11941debfc3dSmrg 
11951debfc3dSmrg       __shared_ptr(__shared_ptr&& __r) noexcept
11961debfc3dSmrg       : _M_ptr(__r._M_ptr), _M_refcount()
11971debfc3dSmrg       {
11981debfc3dSmrg 	_M_refcount._M_swap(__r._M_refcount);
11991debfc3dSmrg 	__r._M_ptr = 0;
12001debfc3dSmrg       }
12011debfc3dSmrg 
12021debfc3dSmrg       template<typename _Yp, typename = _Compatible<_Yp>>
12031debfc3dSmrg 	__shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept
12041debfc3dSmrg 	: _M_ptr(__r._M_ptr), _M_refcount()
12051debfc3dSmrg 	{
12061debfc3dSmrg 	  _M_refcount._M_swap(__r._M_refcount);
12071debfc3dSmrg 	  __r._M_ptr = 0;
12081debfc3dSmrg 	}
12091debfc3dSmrg 
12101debfc3dSmrg       template<typename _Yp, typename = _Compatible<_Yp>>
12111debfc3dSmrg 	explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r)
12121debfc3dSmrg 	: _M_refcount(__r._M_refcount) // may throw
12131debfc3dSmrg 	{
12141debfc3dSmrg 	  // It is now safe to copy __r._M_ptr, as
12151debfc3dSmrg 	  // _M_refcount(__r._M_refcount) did not throw.
12161debfc3dSmrg 	  _M_ptr = __r._M_ptr;
12171debfc3dSmrg 	}
12181debfc3dSmrg 
12191debfc3dSmrg       // If an exception is thrown this constructor has no effect.
12201debfc3dSmrg       template<typename _Yp, typename _Del,
12211debfc3dSmrg 	       typename = _UniqCompatible<_Yp, _Del>>
12221debfc3dSmrg 	__shared_ptr(unique_ptr<_Yp, _Del>&& __r)
12231debfc3dSmrg 	: _M_ptr(__r.get()), _M_refcount()
12241debfc3dSmrg 	{
1225a2dc1f3fSmrg 	  auto __raw = __to_address(__r.get());
12261debfc3dSmrg 	  _M_refcount = __shared_count<_Lp>(std::move(__r));
12271debfc3dSmrg 	  _M_enable_shared_from_this_with(__raw);
12281debfc3dSmrg 	}
12291debfc3dSmrg 
12301debfc3dSmrg #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
12311debfc3dSmrg     protected:
12321debfc3dSmrg       // If an exception is thrown this constructor has no effect.
12331debfc3dSmrg       template<typename _Tp1, typename _Del,
12341debfc3dSmrg 	       typename enable_if<__and_<
12351debfc3dSmrg 		 __not_<is_array<_Tp>>, is_array<_Tp1>,
12361debfc3dSmrg 	         is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*>
12371debfc3dSmrg 	       >::value, bool>::type = true>
12381debfc3dSmrg 	__shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete)
12391debfc3dSmrg 	: _M_ptr(__r.get()), _M_refcount()
12401debfc3dSmrg 	{
1241a2dc1f3fSmrg 	  auto __raw = __to_address(__r.get());
12421debfc3dSmrg 	  _M_refcount = __shared_count<_Lp>(std::move(__r));
12431debfc3dSmrg 	  _M_enable_shared_from_this_with(__raw);
12441debfc3dSmrg 	}
12451debfc3dSmrg     public:
12461debfc3dSmrg #endif
12471debfc3dSmrg 
12481debfc3dSmrg #if _GLIBCXX_USE_DEPRECATED
1249a2dc1f3fSmrg #pragma GCC diagnostic push
1250a2dc1f3fSmrg #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
12511debfc3dSmrg       // Postcondition: use_count() == 1 and __r.get() == 0
12521debfc3dSmrg       template<typename _Yp, typename = _Compatible<_Yp>>
12531debfc3dSmrg 	__shared_ptr(auto_ptr<_Yp>&& __r);
1254a2dc1f3fSmrg #pragma GCC diagnostic pop
12551debfc3dSmrg #endif
12561debfc3dSmrg 
12571debfc3dSmrg       constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
12581debfc3dSmrg 
12591debfc3dSmrg       template<typename _Yp>
12601debfc3dSmrg 	_Assignable<_Yp>
12611debfc3dSmrg 	operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
12621debfc3dSmrg 	{
12631debfc3dSmrg 	  _M_ptr = __r._M_ptr;
12641debfc3dSmrg 	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
12651debfc3dSmrg 	  return *this;
12661debfc3dSmrg 	}
12671debfc3dSmrg 
12681debfc3dSmrg #if _GLIBCXX_USE_DEPRECATED
1269a2dc1f3fSmrg #pragma GCC diagnostic push
1270a2dc1f3fSmrg #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
12711debfc3dSmrg       template<typename _Yp>
12721debfc3dSmrg 	_Assignable<_Yp>
12731debfc3dSmrg 	operator=(auto_ptr<_Yp>&& __r)
12741debfc3dSmrg 	{
12751debfc3dSmrg 	  __shared_ptr(std::move(__r)).swap(*this);
12761debfc3dSmrg 	  return *this;
12771debfc3dSmrg 	}
1278a2dc1f3fSmrg #pragma GCC diagnostic pop
12791debfc3dSmrg #endif
12801debfc3dSmrg 
12811debfc3dSmrg       __shared_ptr&
12821debfc3dSmrg       operator=(__shared_ptr&& __r) noexcept
12831debfc3dSmrg       {
12841debfc3dSmrg 	__shared_ptr(std::move(__r)).swap(*this);
12851debfc3dSmrg 	return *this;
12861debfc3dSmrg       }
12871debfc3dSmrg 
12881debfc3dSmrg       template<class _Yp>
12891debfc3dSmrg 	_Assignable<_Yp>
12901debfc3dSmrg 	operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept
12911debfc3dSmrg 	{
12921debfc3dSmrg 	  __shared_ptr(std::move(__r)).swap(*this);
12931debfc3dSmrg 	  return *this;
12941debfc3dSmrg 	}
12951debfc3dSmrg 
12961debfc3dSmrg       template<typename _Yp, typename _Del>
12971debfc3dSmrg 	_UniqAssignable<_Yp, _Del>
12981debfc3dSmrg 	operator=(unique_ptr<_Yp, _Del>&& __r)
12991debfc3dSmrg 	{
13001debfc3dSmrg 	  __shared_ptr(std::move(__r)).swap(*this);
13011debfc3dSmrg 	  return *this;
13021debfc3dSmrg 	}
13031debfc3dSmrg 
13041debfc3dSmrg       void
13051debfc3dSmrg       reset() noexcept
13061debfc3dSmrg       { __shared_ptr().swap(*this); }
13071debfc3dSmrg 
13081debfc3dSmrg       template<typename _Yp>
13091debfc3dSmrg 	_SafeConv<_Yp>
13101debfc3dSmrg 	reset(_Yp* __p) // _Yp must be complete.
13111debfc3dSmrg 	{
13121debfc3dSmrg 	  // Catch self-reset errors.
13131debfc3dSmrg 	  __glibcxx_assert(__p == 0 || __p != _M_ptr);
13141debfc3dSmrg 	  __shared_ptr(__p).swap(*this);
13151debfc3dSmrg 	}
13161debfc3dSmrg 
13171debfc3dSmrg       template<typename _Yp, typename _Deleter>
13181debfc3dSmrg 	_SafeConv<_Yp>
13191debfc3dSmrg 	reset(_Yp* __p, _Deleter __d)
13201debfc3dSmrg 	{ __shared_ptr(__p, std::move(__d)).swap(*this); }
13211debfc3dSmrg 
13221debfc3dSmrg       template<typename _Yp, typename _Deleter, typename _Alloc>
13231debfc3dSmrg 	_SafeConv<_Yp>
13241debfc3dSmrg 	reset(_Yp* __p, _Deleter __d, _Alloc __a)
13251debfc3dSmrg         { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); }
13261debfc3dSmrg 
13278feb0f0bSmrg       /// Return the stored pointer.
13281debfc3dSmrg       element_type*
13291debfc3dSmrg       get() const noexcept
13301debfc3dSmrg       { return _M_ptr; }
13311debfc3dSmrg 
13328feb0f0bSmrg       /// Return true if the stored pointer is not null.
13331debfc3dSmrg       explicit operator bool() const // never throws
13341debfc3dSmrg       { return _M_ptr == 0 ? false : true; }
13351debfc3dSmrg 
13368feb0f0bSmrg       /// Return true if use_count() == 1.
13371debfc3dSmrg       bool
13381debfc3dSmrg       unique() const noexcept
13391debfc3dSmrg       { return _M_refcount._M_unique(); }
13401debfc3dSmrg 
13418feb0f0bSmrg       /// If *this owns a pointer, return the number of owners, otherwise zero.
13421debfc3dSmrg       long
13431debfc3dSmrg       use_count() const noexcept
13441debfc3dSmrg       { return _M_refcount._M_get_use_count(); }
13451debfc3dSmrg 
13468feb0f0bSmrg       /// Exchange both the owned pointer and the stored pointer.
13471debfc3dSmrg       void
13481debfc3dSmrg       swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
13491debfc3dSmrg       {
13501debfc3dSmrg 	std::swap(_M_ptr, __other._M_ptr);
13511debfc3dSmrg 	_M_refcount._M_swap(__other._M_refcount);
13521debfc3dSmrg       }
13531debfc3dSmrg 
13548feb0f0bSmrg       /** @brief Define an ordering based on ownership.
13558feb0f0bSmrg        *
13568feb0f0bSmrg        * This function defines a strict weak ordering between two shared_ptr
13578feb0f0bSmrg        * or weak_ptr objects, such that one object is less than the other
13588feb0f0bSmrg        * unless they share ownership of the same pointer, or are both empty.
13598feb0f0bSmrg        * @{
13608feb0f0bSmrg       */
13611debfc3dSmrg       template<typename _Tp1>
13621debfc3dSmrg 	bool
13631debfc3dSmrg 	owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept
13641debfc3dSmrg 	{ return _M_refcount._M_less(__rhs._M_refcount); }
13651debfc3dSmrg 
13661debfc3dSmrg       template<typename _Tp1>
13671debfc3dSmrg 	bool
13681debfc3dSmrg 	owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept
13691debfc3dSmrg 	{ return _M_refcount._M_less(__rhs._M_refcount); }
13708feb0f0bSmrg       /// @}
13711debfc3dSmrg 
13721debfc3dSmrg     protected:
13731debfc3dSmrg       // This constructor is non-standard, it is used by allocate_shared.
13741debfc3dSmrg       template<typename _Alloc, typename... _Args>
1375a2dc1f3fSmrg 	__shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
1376a2dc1f3fSmrg 	: _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
1377a2dc1f3fSmrg 	{ _M_enable_shared_from_this_with(_M_ptr); }
13781debfc3dSmrg 
13791debfc3dSmrg       template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
13801debfc3dSmrg 	       typename... _Args>
13811debfc3dSmrg 	friend __shared_ptr<_Tp1, _Lp1>
13821debfc3dSmrg 	__allocate_shared(const _Alloc& __a, _Args&&... __args);
13831debfc3dSmrg 
13841debfc3dSmrg       // This constructor is used by __weak_ptr::lock() and
13851debfc3dSmrg       // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
13861debfc3dSmrg       __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t)
13871debfc3dSmrg       : _M_refcount(__r._M_refcount, std::nothrow)
13881debfc3dSmrg       {
13891debfc3dSmrg 	_M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr;
13901debfc3dSmrg       }
13911debfc3dSmrg 
13921debfc3dSmrg       friend class __weak_ptr<_Tp, _Lp>;
13931debfc3dSmrg 
13941debfc3dSmrg     private:
13951debfc3dSmrg 
13961debfc3dSmrg       template<typename _Yp>
13971debfc3dSmrg 	using __esft_base_t = decltype(__enable_shared_from_this_base(
13981debfc3dSmrg 	      std::declval<const __shared_count<_Lp>&>(),
13991debfc3dSmrg 	      std::declval<_Yp*>()));
14001debfc3dSmrg 
14011debfc3dSmrg       // Detect an accessible and unambiguous enable_shared_from_this base.
14021debfc3dSmrg       template<typename _Yp, typename = void>
14031debfc3dSmrg 	struct __has_esft_base
14041debfc3dSmrg 	: false_type { };
14051debfc3dSmrg 
14061debfc3dSmrg       template<typename _Yp>
14071debfc3dSmrg 	struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
14081debfc3dSmrg 	: __not_<is_array<_Tp>> { }; // No enable shared_from_this for arrays
14091debfc3dSmrg 
14101debfc3dSmrg       template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
14111debfc3dSmrg 	typename enable_if<__has_esft_base<_Yp2>::value>::type
14121debfc3dSmrg 	_M_enable_shared_from_this_with(_Yp* __p) noexcept
14131debfc3dSmrg 	{
14141debfc3dSmrg 	  if (auto __base = __enable_shared_from_this_base(_M_refcount, __p))
14151debfc3dSmrg 	    __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount);
14161debfc3dSmrg 	}
14171debfc3dSmrg 
14181debfc3dSmrg       template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
14191debfc3dSmrg 	typename enable_if<!__has_esft_base<_Yp2>::value>::type
14201debfc3dSmrg 	_M_enable_shared_from_this_with(_Yp*) noexcept
14211debfc3dSmrg 	{ }
14221debfc3dSmrg 
14231debfc3dSmrg       void*
14241debfc3dSmrg       _M_get_deleter(const std::type_info& __ti) const noexcept
14251debfc3dSmrg       { return _M_refcount._M_get_deleter(__ti); }
14261debfc3dSmrg 
14271debfc3dSmrg       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
14281debfc3dSmrg       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
14291debfc3dSmrg 
14301debfc3dSmrg       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
14311debfc3dSmrg 	friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
14321debfc3dSmrg 
1433a2dc1f3fSmrg       template<typename _Del, typename _Tp1>
1434a2dc1f3fSmrg 	friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept;
1435a2dc1f3fSmrg 
14361debfc3dSmrg       element_type*	   _M_ptr;         // Contained pointer.
14371debfc3dSmrg       __shared_count<_Lp>  _M_refcount;    // Reference counter.
14381debfc3dSmrg     };
14391debfc3dSmrg 
14401debfc3dSmrg 
14411debfc3dSmrg   // 20.7.2.2.7 shared_ptr comparisons
14421debfc3dSmrg   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
14431debfc3dSmrg     inline bool
14441debfc3dSmrg     operator==(const __shared_ptr<_Tp1, _Lp>& __a,
14451debfc3dSmrg 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
14461debfc3dSmrg     { return __a.get() == __b.get(); }
14471debfc3dSmrg 
14481debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
14491debfc3dSmrg     inline bool
14501debfc3dSmrg     operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
14511debfc3dSmrg     { return !__a; }
14521debfc3dSmrg 
14538feb0f0bSmrg #ifdef __cpp_lib_three_way_comparison
14548feb0f0bSmrg   template<typename _Tp, typename _Up, _Lock_policy _Lp>
14558feb0f0bSmrg     inline strong_ordering
14568feb0f0bSmrg     operator<=>(const __shared_ptr<_Tp, _Lp>& __a,
14578feb0f0bSmrg 		const __shared_ptr<_Up, _Lp>& __b) noexcept
14588feb0f0bSmrg     { return compare_three_way()(__a.get(), __b.get()); }
14598feb0f0bSmrg 
14608feb0f0bSmrg   template<typename _Tp, _Lock_policy _Lp>
14618feb0f0bSmrg     inline strong_ordering
14628feb0f0bSmrg     operator<=>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
14638feb0f0bSmrg     {
14648feb0f0bSmrg       using pointer = typename __shared_ptr<_Tp, _Lp>::element_type*;
14658feb0f0bSmrg       return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
14668feb0f0bSmrg     }
14678feb0f0bSmrg #else
14681debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
14691debfc3dSmrg     inline bool
14701debfc3dSmrg     operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
14711debfc3dSmrg     { return !__a; }
14721debfc3dSmrg 
14731debfc3dSmrg   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
14741debfc3dSmrg     inline bool
14751debfc3dSmrg     operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
14761debfc3dSmrg 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
14771debfc3dSmrg     { return __a.get() != __b.get(); }
14781debfc3dSmrg 
14791debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
14801debfc3dSmrg     inline bool
14811debfc3dSmrg     operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
14821debfc3dSmrg     { return (bool)__a; }
14831debfc3dSmrg 
14841debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
14851debfc3dSmrg     inline bool
14861debfc3dSmrg     operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
14871debfc3dSmrg     { return (bool)__a; }
14881debfc3dSmrg 
14891debfc3dSmrg   template<typename _Tp, typename _Up, _Lock_policy _Lp>
14901debfc3dSmrg     inline bool
14911debfc3dSmrg     operator<(const __shared_ptr<_Tp, _Lp>& __a,
14921debfc3dSmrg 	      const __shared_ptr<_Up, _Lp>& __b) noexcept
14931debfc3dSmrg     {
14941debfc3dSmrg       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
14951debfc3dSmrg       using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type;
14961debfc3dSmrg       using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
14971debfc3dSmrg       return less<_Vp>()(__a.get(), __b.get());
14981debfc3dSmrg     }
14991debfc3dSmrg 
15001debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
15011debfc3dSmrg     inline bool
15021debfc3dSmrg     operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
15031debfc3dSmrg     {
15041debfc3dSmrg       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
15051debfc3dSmrg       return less<_Tp_elt*>()(__a.get(), nullptr);
15061debfc3dSmrg     }
15071debfc3dSmrg 
15081debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
15091debfc3dSmrg     inline bool
15101debfc3dSmrg     operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
15111debfc3dSmrg     {
15121debfc3dSmrg       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
15131debfc3dSmrg       return less<_Tp_elt*>()(nullptr, __a.get());
15141debfc3dSmrg     }
15151debfc3dSmrg 
15161debfc3dSmrg   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
15171debfc3dSmrg     inline bool
15181debfc3dSmrg     operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
15191debfc3dSmrg 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
15201debfc3dSmrg     { return !(__b < __a); }
15211debfc3dSmrg 
15221debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
15231debfc3dSmrg     inline bool
15241debfc3dSmrg     operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
15251debfc3dSmrg     { return !(nullptr < __a); }
15261debfc3dSmrg 
15271debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
15281debfc3dSmrg     inline bool
15291debfc3dSmrg     operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
15301debfc3dSmrg     { return !(__a < nullptr); }
15311debfc3dSmrg 
15321debfc3dSmrg   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
15331debfc3dSmrg     inline bool
15341debfc3dSmrg     operator>(const __shared_ptr<_Tp1, _Lp>& __a,
15351debfc3dSmrg 	      const __shared_ptr<_Tp2, _Lp>& __b) noexcept
15361debfc3dSmrg     { return (__b < __a); }
15371debfc3dSmrg 
15381debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
15391debfc3dSmrg     inline bool
15401debfc3dSmrg     operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
15411debfc3dSmrg     { return nullptr < __a; }
15421debfc3dSmrg 
15431debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
15441debfc3dSmrg     inline bool
15451debfc3dSmrg     operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
15461debfc3dSmrg     { return __a < nullptr; }
15471debfc3dSmrg 
15481debfc3dSmrg   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
15491debfc3dSmrg     inline bool
15501debfc3dSmrg     operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
15511debfc3dSmrg 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
15521debfc3dSmrg     { return !(__a < __b); }
15531debfc3dSmrg 
15541debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
15551debfc3dSmrg     inline bool
15561debfc3dSmrg     operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
15571debfc3dSmrg     { return !(__a < nullptr); }
15581debfc3dSmrg 
15591debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
15601debfc3dSmrg     inline bool
15611debfc3dSmrg     operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
15621debfc3dSmrg     { return !(nullptr < __a); }
15638feb0f0bSmrg #endif // three-way comparison
15641debfc3dSmrg 
15651debfc3dSmrg   // 20.7.2.2.8 shared_ptr specialized algorithms.
15661debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
15671debfc3dSmrg     inline void
15681debfc3dSmrg     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
15691debfc3dSmrg     { __a.swap(__b); }
15701debfc3dSmrg 
15711debfc3dSmrg   // 20.7.2.2.9 shared_ptr casts
15721debfc3dSmrg 
15731debfc3dSmrg   // The seemingly equivalent code:
15741debfc3dSmrg   // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
15751debfc3dSmrg   // will eventually result in undefined behaviour, attempting to
15761debfc3dSmrg   // delete the same object twice.
15771debfc3dSmrg   /// static_pointer_cast
15781debfc3dSmrg   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
15791debfc3dSmrg     inline __shared_ptr<_Tp, _Lp>
15801debfc3dSmrg     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
15811debfc3dSmrg     {
15821debfc3dSmrg       using _Sp = __shared_ptr<_Tp, _Lp>;
15831debfc3dSmrg       return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
15841debfc3dSmrg     }
15851debfc3dSmrg 
15861debfc3dSmrg   // The seemingly equivalent code:
15871debfc3dSmrg   // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
15881debfc3dSmrg   // will eventually result in undefined behaviour, attempting to
15891debfc3dSmrg   // delete the same object twice.
15901debfc3dSmrg   /// const_pointer_cast
15911debfc3dSmrg   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
15921debfc3dSmrg     inline __shared_ptr<_Tp, _Lp>
15931debfc3dSmrg     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
15941debfc3dSmrg     {
15951debfc3dSmrg       using _Sp = __shared_ptr<_Tp, _Lp>;
15961debfc3dSmrg       return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
15971debfc3dSmrg     }
15981debfc3dSmrg 
15991debfc3dSmrg   // The seemingly equivalent code:
16001debfc3dSmrg   // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
16011debfc3dSmrg   // will eventually result in undefined behaviour, attempting to
16021debfc3dSmrg   // delete the same object twice.
16031debfc3dSmrg   /// dynamic_pointer_cast
16041debfc3dSmrg   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
16051debfc3dSmrg     inline __shared_ptr<_Tp, _Lp>
16061debfc3dSmrg     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
16071debfc3dSmrg     {
16081debfc3dSmrg       using _Sp = __shared_ptr<_Tp, _Lp>;
16091debfc3dSmrg       if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
16101debfc3dSmrg 	return _Sp(__r, __p);
16111debfc3dSmrg       return _Sp();
16121debfc3dSmrg     }
16131debfc3dSmrg 
16141debfc3dSmrg #if __cplusplus > 201402L
16151debfc3dSmrg   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
16161debfc3dSmrg     inline __shared_ptr<_Tp, _Lp>
16171debfc3dSmrg     reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
16181debfc3dSmrg     {
16191debfc3dSmrg       using _Sp = __shared_ptr<_Tp, _Lp>;
16201debfc3dSmrg       return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
16211debfc3dSmrg     }
16221debfc3dSmrg #endif
16231debfc3dSmrg 
16241debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
16251debfc3dSmrg     class __weak_ptr
16261debfc3dSmrg     {
16271debfc3dSmrg       template<typename _Yp, typename _Res = void>
16281debfc3dSmrg 	using _Compatible = typename
16291debfc3dSmrg 	  enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
16301debfc3dSmrg 
16311debfc3dSmrg       // Constraint for assignment from shared_ptr and weak_ptr:
16321debfc3dSmrg       template<typename _Yp>
16331debfc3dSmrg 	using _Assignable = _Compatible<_Yp, __weak_ptr&>;
16341debfc3dSmrg 
16351debfc3dSmrg     public:
16361debfc3dSmrg       using element_type = typename remove_extent<_Tp>::type;
16371debfc3dSmrg 
16381debfc3dSmrg       constexpr __weak_ptr() noexcept
16391debfc3dSmrg       : _M_ptr(nullptr), _M_refcount()
16401debfc3dSmrg       { }
16411debfc3dSmrg 
16421debfc3dSmrg       __weak_ptr(const __weak_ptr&) noexcept = default;
16431debfc3dSmrg 
16441debfc3dSmrg       ~__weak_ptr() = default;
16451debfc3dSmrg 
16461debfc3dSmrg       // The "obvious" converting constructor implementation:
16471debfc3dSmrg       //
16481debfc3dSmrg       //  template<typename _Tp1>
16491debfc3dSmrg       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
16501debfc3dSmrg       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
16511debfc3dSmrg       //    { }
16521debfc3dSmrg       //
16531debfc3dSmrg       // has a serious problem.
16541debfc3dSmrg       //
16551debfc3dSmrg       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
16561debfc3dSmrg       //  conversion may require access to *__r._M_ptr (virtual inheritance).
16571debfc3dSmrg       //
16581debfc3dSmrg       // It is not possible to avoid spurious access violations since
16591debfc3dSmrg       // in multithreaded programs __r._M_ptr may be invalidated at any point.
16601debfc3dSmrg       template<typename _Yp, typename = _Compatible<_Yp>>
16611debfc3dSmrg 	__weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept
16621debfc3dSmrg 	: _M_refcount(__r._M_refcount)
16631debfc3dSmrg         { _M_ptr = __r.lock().get(); }
16641debfc3dSmrg 
16651debfc3dSmrg       template<typename _Yp, typename = _Compatible<_Yp>>
16661debfc3dSmrg 	__weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
16671debfc3dSmrg 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
16681debfc3dSmrg 	{ }
16691debfc3dSmrg 
16701debfc3dSmrg       __weak_ptr(__weak_ptr&& __r) noexcept
16711debfc3dSmrg       : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
16721debfc3dSmrg       { __r._M_ptr = nullptr; }
16731debfc3dSmrg 
16741debfc3dSmrg       template<typename _Yp, typename = _Compatible<_Yp>>
16751debfc3dSmrg 	__weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept
16761debfc3dSmrg 	: _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount))
16771debfc3dSmrg         { __r._M_ptr = nullptr; }
16781debfc3dSmrg 
16791debfc3dSmrg       __weak_ptr&
16801debfc3dSmrg       operator=(const __weak_ptr& __r) noexcept = default;
16811debfc3dSmrg 
16821debfc3dSmrg       template<typename _Yp>
16831debfc3dSmrg 	_Assignable<_Yp>
16841debfc3dSmrg 	operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept
16851debfc3dSmrg 	{
16861debfc3dSmrg 	  _M_ptr = __r.lock().get();
16871debfc3dSmrg 	  _M_refcount = __r._M_refcount;
16881debfc3dSmrg 	  return *this;
16891debfc3dSmrg 	}
16901debfc3dSmrg 
16911debfc3dSmrg       template<typename _Yp>
16921debfc3dSmrg 	_Assignable<_Yp>
16931debfc3dSmrg 	operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
16941debfc3dSmrg 	{
16951debfc3dSmrg 	  _M_ptr = __r._M_ptr;
16961debfc3dSmrg 	  _M_refcount = __r._M_refcount;
16971debfc3dSmrg 	  return *this;
16981debfc3dSmrg 	}
16991debfc3dSmrg 
17001debfc3dSmrg       __weak_ptr&
17011debfc3dSmrg       operator=(__weak_ptr&& __r) noexcept
17021debfc3dSmrg       {
1703*23f5f463Smrg 	__weak_ptr(std::move(__r)).swap(*this);
17041debfc3dSmrg 	return *this;
17051debfc3dSmrg       }
17061debfc3dSmrg 
17071debfc3dSmrg       template<typename _Yp>
17081debfc3dSmrg 	_Assignable<_Yp>
17091debfc3dSmrg 	operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept
17101debfc3dSmrg 	{
17111debfc3dSmrg 	  _M_ptr = __r.lock().get();
17121debfc3dSmrg 	  _M_refcount = std::move(__r._M_refcount);
17131debfc3dSmrg 	  __r._M_ptr = nullptr;
17141debfc3dSmrg 	  return *this;
17151debfc3dSmrg 	}
17161debfc3dSmrg 
17171debfc3dSmrg       __shared_ptr<_Tp, _Lp>
17181debfc3dSmrg       lock() const noexcept
17191debfc3dSmrg       { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); }
17201debfc3dSmrg 
17211debfc3dSmrg       long
17221debfc3dSmrg       use_count() const noexcept
17231debfc3dSmrg       { return _M_refcount._M_get_use_count(); }
17241debfc3dSmrg 
17251debfc3dSmrg       bool
17261debfc3dSmrg       expired() const noexcept
17271debfc3dSmrg       { return _M_refcount._M_get_use_count() == 0; }
17281debfc3dSmrg 
17291debfc3dSmrg       template<typename _Tp1>
17301debfc3dSmrg 	bool
17311debfc3dSmrg 	owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept
17321debfc3dSmrg 	{ return _M_refcount._M_less(__rhs._M_refcount); }
17331debfc3dSmrg 
17341debfc3dSmrg       template<typename _Tp1>
17351debfc3dSmrg 	bool
17361debfc3dSmrg 	owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept
17371debfc3dSmrg 	{ return _M_refcount._M_less(__rhs._M_refcount); }
17381debfc3dSmrg 
17391debfc3dSmrg       void
17401debfc3dSmrg       reset() noexcept
17411debfc3dSmrg       { __weak_ptr().swap(*this); }
17421debfc3dSmrg 
17431debfc3dSmrg       void
17441debfc3dSmrg       swap(__weak_ptr& __s) noexcept
17451debfc3dSmrg       {
17461debfc3dSmrg 	std::swap(_M_ptr, __s._M_ptr);
17471debfc3dSmrg 	_M_refcount._M_swap(__s._M_refcount);
17481debfc3dSmrg       }
17491debfc3dSmrg 
17501debfc3dSmrg     private:
17511debfc3dSmrg       // Used by __enable_shared_from_this.
17521debfc3dSmrg       void
17531debfc3dSmrg       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
17541debfc3dSmrg       {
17551debfc3dSmrg 	if (use_count() == 0)
17561debfc3dSmrg 	  {
17571debfc3dSmrg 	    _M_ptr = __ptr;
17581debfc3dSmrg 	    _M_refcount = __refcount;
17591debfc3dSmrg 	  }
17601debfc3dSmrg       }
17611debfc3dSmrg 
17621debfc3dSmrg       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
17631debfc3dSmrg       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
17641debfc3dSmrg       friend class __enable_shared_from_this<_Tp, _Lp>;
17651debfc3dSmrg       friend class enable_shared_from_this<_Tp>;
17661debfc3dSmrg 
17671debfc3dSmrg       element_type*	 _M_ptr;         // Contained pointer.
17681debfc3dSmrg       __weak_count<_Lp>  _M_refcount;    // Reference counter.
17691debfc3dSmrg     };
17701debfc3dSmrg 
17711debfc3dSmrg   // 20.7.2.3.6 weak_ptr specialized algorithms.
17721debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
17731debfc3dSmrg     inline void
17741debfc3dSmrg     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
17751debfc3dSmrg     { __a.swap(__b); }
17761debfc3dSmrg 
17771debfc3dSmrg   template<typename _Tp, typename _Tp1>
17781debfc3dSmrg     struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
17791debfc3dSmrg     {
17801debfc3dSmrg       bool
17811debfc3dSmrg       operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept
17821debfc3dSmrg       { return __lhs.owner_before(__rhs); }
17831debfc3dSmrg 
17841debfc3dSmrg       bool
17851debfc3dSmrg       operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept
17861debfc3dSmrg       { return __lhs.owner_before(__rhs); }
17871debfc3dSmrg 
17881debfc3dSmrg       bool
17891debfc3dSmrg       operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept
17901debfc3dSmrg       { return __lhs.owner_before(__rhs); }
17911debfc3dSmrg     };
17921debfc3dSmrg 
17931debfc3dSmrg   template<>
17941debfc3dSmrg     struct _Sp_owner_less<void, void>
17951debfc3dSmrg     {
17961debfc3dSmrg       template<typename _Tp, typename _Up>
17971debfc3dSmrg 	auto
17981debfc3dSmrg 	operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept
17991debfc3dSmrg 	-> decltype(__lhs.owner_before(__rhs))
18001debfc3dSmrg 	{ return __lhs.owner_before(__rhs); }
18011debfc3dSmrg 
18021debfc3dSmrg       using is_transparent = void;
18031debfc3dSmrg     };
18041debfc3dSmrg 
18051debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
18061debfc3dSmrg     struct owner_less<__shared_ptr<_Tp, _Lp>>
18071debfc3dSmrg     : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
18081debfc3dSmrg     { };
18091debfc3dSmrg 
18101debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
18111debfc3dSmrg     struct owner_less<__weak_ptr<_Tp, _Lp>>
18121debfc3dSmrg     : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
18131debfc3dSmrg     { };
18141debfc3dSmrg 
18151debfc3dSmrg 
18161debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
18171debfc3dSmrg     class __enable_shared_from_this
18181debfc3dSmrg     {
18191debfc3dSmrg     protected:
18201debfc3dSmrg       constexpr __enable_shared_from_this() noexcept { }
18211debfc3dSmrg 
18221debfc3dSmrg       __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
18231debfc3dSmrg 
18241debfc3dSmrg       __enable_shared_from_this&
18251debfc3dSmrg       operator=(const __enable_shared_from_this&) noexcept
18261debfc3dSmrg       { return *this; }
18271debfc3dSmrg 
18281debfc3dSmrg       ~__enable_shared_from_this() { }
18291debfc3dSmrg 
18301debfc3dSmrg     public:
18311debfc3dSmrg       __shared_ptr<_Tp, _Lp>
18321debfc3dSmrg       shared_from_this()
18331debfc3dSmrg       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
18341debfc3dSmrg 
18351debfc3dSmrg       __shared_ptr<const _Tp, _Lp>
18361debfc3dSmrg       shared_from_this() const
18371debfc3dSmrg       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
18381debfc3dSmrg 
18391debfc3dSmrg #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
18401debfc3dSmrg       __weak_ptr<_Tp, _Lp>
18411debfc3dSmrg       weak_from_this() noexcept
18421debfc3dSmrg       { return this->_M_weak_this; }
18431debfc3dSmrg 
18441debfc3dSmrg       __weak_ptr<const _Tp, _Lp>
18451debfc3dSmrg       weak_from_this() const noexcept
18461debfc3dSmrg       { return this->_M_weak_this; }
18471debfc3dSmrg #endif
18481debfc3dSmrg 
18491debfc3dSmrg     private:
18501debfc3dSmrg       template<typename _Tp1>
18511debfc3dSmrg 	void
18521debfc3dSmrg 	_M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
18531debfc3dSmrg 	{ _M_weak_this._M_assign(__p, __n); }
18541debfc3dSmrg 
18551debfc3dSmrg       friend const __enable_shared_from_this*
18561debfc3dSmrg       __enable_shared_from_this_base(const __shared_count<_Lp>&,
18571debfc3dSmrg 				     const __enable_shared_from_this* __p)
18581debfc3dSmrg       { return __p; }
18591debfc3dSmrg 
18601debfc3dSmrg       template<typename, _Lock_policy>
18611debfc3dSmrg 	friend class __shared_ptr;
18621debfc3dSmrg 
18631debfc3dSmrg       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
18641debfc3dSmrg     };
18651debfc3dSmrg 
1866c0a68be4Smrg   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
1867c0a68be4Smrg 	   typename _Alloc, typename... _Args>
18681debfc3dSmrg     inline __shared_ptr<_Tp, _Lp>
18691debfc3dSmrg     __allocate_shared(const _Alloc& __a, _Args&&... __args)
18701debfc3dSmrg     {
18718feb0f0bSmrg       static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported");
18728feb0f0bSmrg 
1873a2dc1f3fSmrg       return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a},
18741debfc3dSmrg 				    std::forward<_Args>(__args)...);
18751debfc3dSmrg     }
18761debfc3dSmrg 
1877c0a68be4Smrg   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
1878c0a68be4Smrg 	   typename... _Args>
18791debfc3dSmrg     inline __shared_ptr<_Tp, _Lp>
18801debfc3dSmrg     __make_shared(_Args&&... __args)
18811debfc3dSmrg     {
18821debfc3dSmrg       typedef typename std::remove_const<_Tp>::type _Tp_nc;
18831debfc3dSmrg       return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
18841debfc3dSmrg 					      std::forward<_Args>(__args)...);
18851debfc3dSmrg     }
18861debfc3dSmrg 
18871debfc3dSmrg   /// std::hash specialization for __shared_ptr.
18881debfc3dSmrg   template<typename _Tp, _Lock_policy _Lp>
18891debfc3dSmrg     struct hash<__shared_ptr<_Tp, _Lp>>
18901debfc3dSmrg     : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
18911debfc3dSmrg     {
18921debfc3dSmrg       size_t
18931debfc3dSmrg       operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
18941debfc3dSmrg       {
18951debfc3dSmrg 	return hash<typename __shared_ptr<_Tp, _Lp>::element_type*>()(
18961debfc3dSmrg 	    __s.get());
18971debfc3dSmrg       }
18981debfc3dSmrg     };
18991debfc3dSmrg 
19001debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
19011debfc3dSmrg } // namespace
19021debfc3dSmrg 
19031debfc3dSmrg #endif // _SHARED_PTR_BASE_H
1904