1  // Experimental shared_ptr with array support -*- C++ -*-
       2  
       3  // Copyright (C) 2015-2023 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  /** @file experimental/bits/shared_ptr.h
      26   *  This is an internal header file, included by other library headers.
      27   *  Do not attempt to use it directly. @headername{experimental/memory}
      28   */
      29  
      30  #ifndef _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H
      31  #define _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 1
      32  
      33  #pragma GCC system_header
      34  
      35  #if __cplusplus >= 201402L
      36  
      37  #include <memory>
      38  #include <experimental/type_traits>
      39  
      40  namespace std _GLIBCXX_VISIBILITY(default)
      41  {
      42  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      43  
      44  namespace experimental
      45  {
      46  inline namespace fundamentals_v2
      47  {
      48    // 8.2.1
      49  
      50    template<typename _Tp> class shared_ptr;
      51    template<typename _Tp> class weak_ptr;
      52    template<typename _Tp> class enable_shared_from_this;
      53  
      54    template<typename _Yp, typename _Tp>
      55      constexpr bool __sp_compatible_v
      56        = std::__sp_compatible_with<_Yp*, _Tp*>::value;
      57  
      58    template<typename _Tp, typename _Yp>
      59      constexpr bool __sp_is_constructible_v
      60        = std::__sp_is_constructible<_Tp, _Yp>::value;
      61  
      62    template<typename _Tp>
      63      class shared_ptr : public __shared_ptr<_Tp>
      64      {
      65        using _Base_type = __shared_ptr<_Tp>;
      66  
      67      public:
      68        using element_type = typename _Base_type::element_type;
      69  
      70      private:
      71        // Constraint for construction from a pointer of type _Yp*:
      72        template<typename _Yp>
      73  	using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
      74  
      75        template<typename _Tp1, typename _Res = void>
      76  	using _Compatible
      77  	  = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
      78  
      79        template<typename _Tp1, typename _Del,
      80  	       typename _Ptr = typename unique_ptr<_Tp1, _Del>::pointer,
      81  	       typename _Res = void>
      82  	using _UniqCompatible = enable_if_t<
      83  	  __sp_compatible_v<_Tp1, _Tp>
      84  	  && experimental::is_convertible_v<_Ptr, element_type*>,
      85  	  _Res>;
      86  
      87      public:
      88  
      89        // 8.2.1.1, shared_ptr constructors
      90        constexpr shared_ptr() noexcept = default;
      91  
      92        template<typename _Tp1, typename = _SafeConv<_Tp1>>
      93  	explicit
      94  	shared_ptr(_Tp1* __p) : _Base_type(__p)
      95  	{ _M_enable_shared_from_this_with(__p); }
      96  
      97        template<typename _Tp1, typename _Deleter, typename = _SafeConv<_Tp1>>
      98  	shared_ptr(_Tp1* __p, _Deleter __d)
      99  	: _Base_type(__p, __d)
     100  	{ _M_enable_shared_from_this_with(__p); }
     101  
     102        template<typename _Tp1, typename _Deleter, typename _Alloc,
     103  	       typename = _SafeConv<_Tp1>>
     104  	shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
     105  	: _Base_type(__p, __d, __a)
     106  	{ _M_enable_shared_from_this_with(__p); }
     107  
     108        template<typename _Deleter>
     109  	shared_ptr(nullptr_t __p, _Deleter __d)
     110  	: _Base_type(__p, __d) { }
     111  
     112        template<typename _Deleter, typename _Alloc>
     113  	shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
     114  	: _Base_type(__p, __d, __a) { }
     115  
     116        template<typename _Tp1>
     117  	shared_ptr(const shared_ptr<_Tp1>& __r, element_type* __p) noexcept
     118  	: _Base_type(__r, __p) { }
     119  
     120        shared_ptr(const shared_ptr& __r) noexcept
     121  	: _Base_type(__r) { }
     122  
     123        template<typename _Tp1, typename = _Compatible<_Tp1>>
     124  	shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
     125  	: _Base_type(__r) { }
     126  
     127        shared_ptr(shared_ptr&& __r) noexcept
     128        : _Base_type(std::move(__r)) { }
     129  
     130        template<typename _Tp1, typename = _Compatible<_Tp1>>
     131  	shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
     132  	: _Base_type(std::move(__r)) { }
     133  
     134        template<typename _Tp1, typename = _Compatible<_Tp1>>
     135  	explicit
     136  	shared_ptr(const weak_ptr<_Tp1>& __r)
     137  	: _Base_type(__r) { }
     138  
     139  #if _GLIBCXX_USE_DEPRECATED
     140  #pragma GCC diagnostic push
     141  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     142        template<typename _Tp1, typename = _Compatible<_Tp1>>
     143  	shared_ptr(std::auto_ptr<_Tp1>&& __r)
     144  	: _Base_type(std::move(__r))
     145  	{ _M_enable_shared_from_this_with(static_cast<_Tp1*>(this->get())); }
     146  #pragma GCC diagnostic pop
     147  #endif
     148  
     149        template<typename _Tp1, typename _Del,
     150  	       typename = _UniqCompatible<_Tp1, _Del>>
     151  	shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
     152  	: _Base_type(std::move(__r))
     153  	{
     154  	  // XXX assume conversion from __r.get() to this->get() to __elem_t*
     155  	  // is a round trip, which might not be true in all cases.
     156  	  using __elem_t = typename unique_ptr<_Tp1, _Del>::element_type;
     157  	  _M_enable_shared_from_this_with(static_cast<__elem_t*>(this->get()));
     158  	}
     159  
     160        constexpr shared_ptr(nullptr_t __p)
     161        : _Base_type(__p) { }
     162  
     163        // C++14 20.8.2.2
     164        ~shared_ptr() = default;
     165  
     166        // C++14 20.8.2.3
     167        shared_ptr& operator=(const shared_ptr&) noexcept = default;
     168  
     169        template <typename _Tp1>
     170  	_Compatible<_Tp1, shared_ptr&>
     171  	operator=(const shared_ptr<_Tp1>& __r) noexcept
     172  	{
     173  	  _Base_type::operator=(__r);
     174  	  return *this;
     175  	}
     176  
     177        shared_ptr&
     178        operator=(shared_ptr&& __r) noexcept
     179        {
     180  	_Base_type::operator=(std::move(__r));
     181  	return *this;
     182        }
     183  
     184        template <typename _Tp1>
     185  	_Compatible<_Tp1, shared_ptr&>
     186  	operator=(shared_ptr<_Tp1>&& __r) noexcept
     187  	{
     188  	  _Base_type::operator=(std::move(__r));
     189  	  return *this;
     190  	}
     191  
     192  #if _GLIBCXX_USE_DEPRECATED
     193  #pragma GCC diagnostic push
     194  #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     195        template<typename _Tp1>
     196  	_Compatible<_Tp1, shared_ptr&>
     197  	operator=(std::auto_ptr<_Tp1>&& __r)
     198  	{
     199  	  __shared_ptr<_Tp>::operator=(std::move(__r));
     200  	  return *this;
     201  	}
     202  #pragma GCC diagnostic pop
     203  #endif
     204  
     205        template <typename _Tp1, typename _Del>
     206  	_UniqCompatible<_Tp1, _Del, shared_ptr&>
     207  	operator=(unique_ptr<_Tp1, _Del>&& __r)
     208  	{
     209  	  _Base_type::operator=(std::move(__r));
     210  	  return *this;
     211  	}
     212  
     213        // C++14 20.8.2.2.4
     214        // swap & reset
     215        // 8.2.1.2 shared_ptr observers
     216        // in __shared_ptr
     217  
     218      private:
     219        template<typename _Alloc, typename... _Args>
     220  	shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
     221  		   _Args&&... __args)
     222  	: _Base_type(__tag, __a, std::forward<_Args>(__args)...)
     223  	{ _M_enable_shared_from_this_with(this->get()); }
     224  
     225        template<typename _Tp1, typename _Alloc, typename... _Args>
     226  	friend shared_ptr<_Tp1>
     227  	allocate_shared(const _Alloc& __a, _Args&&...  __args);
     228  
     229        shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
     230        : _Base_type(__r, std::nothrow) { }
     231  
     232        friend class weak_ptr<_Tp>;
     233  
     234        template<typename _Yp>
     235  	using __esft_base_t =
     236  	  decltype(__expt_enable_shared_from_this_base(std::declval<_Yp*>()));
     237  
     238        // Detect an accessible and unambiguous enable_shared_from_this base.
     239        template<typename _Yp, typename = void>
     240  	struct __has_esft_base
     241  	: false_type { };
     242  
     243        template<typename _Yp>
     244  	struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
     245  	: __bool_constant<!is_array_v<_Tp>> { };  // ignore base for arrays
     246  
     247        template<typename _Yp>
     248  	typename enable_if<__has_esft_base<_Yp>::value>::type
     249  	_M_enable_shared_from_this_with(const _Yp* __p) noexcept
     250  	{
     251  	  if (auto __base = __expt_enable_shared_from_this_base(__p))
     252  	    {
     253  	      __base->_M_weak_this
     254  		= shared_ptr<_Yp>(*this, const_cast<_Yp*>(__p));
     255  	    }
     256  	}
     257  
     258        template<typename _Yp>
     259  	typename enable_if<!__has_esft_base<_Yp>::value>::type
     260  	_M_enable_shared_from_this_with(const _Yp*) noexcept
     261  	{ }
     262      };
     263  
     264    // C++14 20.8.2.2.7
     265    template<typename _Tp1, typename _Tp2>
     266      bool operator==(const shared_ptr<_Tp1>& __a,
     267  		    const shared_ptr<_Tp2>& __b) noexcept
     268      { return __a.get() == __b.get(); }
     269  
     270    template<typename _Tp>
     271      inline bool
     272      operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     273      { return !__a; }
     274  
     275    template<typename _Tp>
     276      inline bool
     277      operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     278      { return !__a; }
     279  
     280    template<typename _Tp1, typename _Tp2>
     281      inline bool
     282      operator!=(const shared_ptr<_Tp1>& __a,
     283  	       const shared_ptr<_Tp2>& __b) noexcept
     284      { return __a.get() != __b.get(); }
     285  
     286    template<typename _Tp>
     287      inline bool
     288      operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     289      { return (bool)__a; }
     290  
     291    template<typename _Tp>
     292      inline bool
     293      operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     294      { return (bool)__a; }
     295  
     296    template<typename _Tp1, typename _Tp2>
     297      inline bool
     298      operator<(const shared_ptr<_Tp1>& __a,
     299  	      const shared_ptr<_Tp2>& __b) noexcept
     300      {
     301        using __elem_t1 = typename shared_ptr<_Tp1>::element_type;
     302        using __elem_t2 = typename shared_ptr<_Tp2>::element_type;
     303        using _CT = common_type_t<__elem_t1*, __elem_t2*>;
     304        return std::less<_CT>()(__a.get(), __b.get());
     305      }
     306  
     307    template<typename _Tp>
     308      inline bool
     309      operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     310      {
     311        using __elem_t = typename shared_ptr<_Tp>::element_type;
     312        return std::less<__elem_t*>()(__a.get(), nullptr);
     313      }
     314  
     315    template<typename _Tp>
     316      inline bool
     317      operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     318      {
     319        using __elem_t = typename shared_ptr<_Tp>::element_type;
     320        return std::less<__elem_t*>()(nullptr, __a.get());
     321      }
     322  
     323    template<typename _Tp1, typename _Tp2>
     324      inline bool
     325      operator<=(const shared_ptr<_Tp1>& __a,
     326  	       const shared_ptr<_Tp2>& __b) noexcept
     327      { return !(__b < __a); }
     328  
     329    template<typename _Tp>
     330      inline bool
     331      operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     332      { return !(nullptr < __a); }
     333  
     334    template<typename _Tp>
     335      inline bool
     336      operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     337      { return !(__a < nullptr); }
     338  
     339    template<typename _Tp1, typename _Tp2>
     340      inline bool
     341      operator>(const shared_ptr<_Tp1>& __a,
     342  	      const shared_ptr<_Tp2>& __b) noexcept
     343      { return (__b < __a); }
     344  
     345    template<typename _Tp>
     346      inline bool
     347      operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     348      {
     349        using __elem_t = typename shared_ptr<_Tp>::element_type;
     350        return std::less<__elem_t*>()(nullptr, __a.get());
     351      }
     352  
     353    template<typename _Tp>
     354      inline bool
     355      operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     356      {
     357        using __elem_t = typename shared_ptr<_Tp>::element_type;
     358        return std::less<__elem_t*>()(__a.get(), nullptr);
     359      }
     360  
     361    template<typename _Tp1, typename _Tp2>
     362      inline bool
     363      operator>=(const shared_ptr<_Tp1>& __a,
     364  	       const shared_ptr<_Tp2>& __b) noexcept
     365      { return !(__a < __b); }
     366  
     367    template<typename _Tp>
     368      inline bool
     369      operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
     370      { return !(__a < nullptr); }
     371  
     372    template<typename _Tp>
     373      inline bool
     374      operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
     375      { return !(nullptr < __a); }
     376  
     377    // C++14 20.8.2.2.8
     378    template<typename _Tp>
     379      inline void
     380      swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
     381      { __a.swap(__b); }
     382  
     383    // 8.2.1.3, shared_ptr casts
     384    template<typename _Tp, typename _Tp1>
     385      inline shared_ptr<_Tp>
     386      static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
     387      {
     388        using __elem_t = typename shared_ptr<_Tp>::element_type;
     389        return shared_ptr<_Tp>(__r, static_cast<__elem_t*>(__r.get()));
     390      }
     391  
     392    template<typename _Tp, typename _Tp1>
     393      inline shared_ptr<_Tp>
     394      dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
     395      {
     396        using __elem_t = typename shared_ptr<_Tp>::element_type;
     397        if (_Tp* __p = dynamic_cast<__elem_t*>(__r.get()))
     398  	return shared_ptr<_Tp>(__r, __p);
     399        return shared_ptr<_Tp>();
     400      }
     401  
     402    template<typename _Tp, typename _Tp1>
     403      inline shared_ptr<_Tp>
     404      const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
     405      {
     406        using __elem_t = typename shared_ptr<_Tp>::element_type;
     407        return shared_ptr<_Tp>(__r, const_cast<__elem_t*>(__r.get()));
     408      }
     409  
     410    template<typename _Tp, typename _Tp1>
     411      inline shared_ptr<_Tp>
     412      reinterpret_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
     413      {
     414        using __elem_t = typename shared_ptr<_Tp>::element_type;
     415        return shared_ptr<_Tp>(__r, reinterpret_cast<__elem_t*>(__r.get()));
     416      }
     417  
     418    // C++14 20.8.2.3
     419    template<typename _Tp>
     420      class weak_ptr : public __weak_ptr<_Tp>
     421      {
     422        template<typename _Tp1, typename _Res = void>
     423  	using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
     424  
     425        using _Base_type = __weak_ptr<_Tp>;
     426  
     427       public:
     428         constexpr weak_ptr() noexcept = default;
     429  
     430         template<typename _Tp1, typename = _Compatible<_Tp1>>
     431  	 weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
     432  	 : _Base_type(__r) { }
     433  
     434         weak_ptr(const weak_ptr&) noexcept = default;
     435  
     436         template<typename _Tp1, typename = _Compatible<_Tp1>>
     437  	 weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
     438  	 : _Base_type(__r) { }
     439  
     440         weak_ptr(weak_ptr&&) noexcept = default;
     441  
     442         template<typename _Tp1, typename = _Compatible<_Tp1>>
     443  	 weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
     444  	 : _Base_type(std::move(__r)) { }
     445  
     446         weak_ptr&
     447         operator=(const weak_ptr& __r) noexcept = default;
     448  
     449         template<typename _Tp1>
     450  	 _Compatible<_Tp1, weak_ptr&>
     451  	 operator=(const weak_ptr<_Tp1>& __r) noexcept
     452  	 {
     453  	   this->_Base_type::operator=(__r);
     454  	   return *this;
     455  	 }
     456  
     457         template<typename _Tp1>
     458  	 _Compatible<_Tp1, weak_ptr&>
     459  	 operator=(const shared_ptr<_Tp1>& __r) noexcept
     460  	 {
     461  	   this->_Base_type::operator=(__r);
     462  	   return *this;
     463  	 }
     464  
     465         weak_ptr&
     466         operator=(weak_ptr&& __r) noexcept = default;
     467  
     468         template<typename _Tp1>
     469  	 _Compatible<_Tp1, weak_ptr&>
     470  	 operator=(weak_ptr<_Tp1>&& __r) noexcept
     471  	 {
     472  	   this->_Base_type::operator=(std::move(__r));
     473  	   return *this;
     474  	 }
     475  
     476         shared_ptr<_Tp>
     477         lock() const noexcept
     478         { return shared_ptr<_Tp>(*this, std::nothrow); }
     479  
     480         friend class enable_shared_from_this<_Tp>;
     481      };
     482  
     483    // C++14 20.8.2.3.6
     484    template<typename _Tp>
     485      inline void
     486      swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
     487      { __a.swap(__b); }
     488  
     489    /// C++14 20.8.2.2.10
     490    template<typename _Del, typename _Tp>
     491      inline _Del*
     492      get_deleter(const shared_ptr<_Tp>& __p) noexcept
     493      { return std::get_deleter<_Del>(__p); }
     494  
     495    // C++14 20.8.2.2.11
     496    template<typename _Ch, typename _Tr, typename _Tp>
     497      inline std::basic_ostream<_Ch, _Tr>&
     498      operator<<(std::basic_ostream<_Ch, _Tr>& __os, const shared_ptr<_Tp>& __p)
     499      {
     500        __os << __p.get();
     501        return __os;
     502      }
     503  
     504    // C++14 20.8.2.4
     505    template<typename _Tp = void> class owner_less;
     506  
     507     /// Partial specialization of owner_less for shared_ptr.
     508    template<typename _Tp>
     509      struct owner_less<shared_ptr<_Tp>>
     510      : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
     511      { };
     512  
     513    /// Partial specialization of owner_less for weak_ptr.
     514    template<typename _Tp>
     515      struct owner_less<weak_ptr<_Tp>>
     516      : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
     517      { };
     518  
     519    template<>
     520      class owner_less<void>
     521      {
     522        template<typename _Tp, typename _Up>
     523          bool
     524          operator()(shared_ptr<_Tp> const& __lhs,
     525                     shared_ptr<_Up> const& __rhs) const
     526          { return __lhs.owner_before(__rhs); }
     527  
     528        template<typename _Tp, typename _Up>
     529          bool
     530          operator()(shared_ptr<_Tp> const& __lhs,
     531                     weak_ptr<_Up> const& __rhs) const
     532          { return __lhs.owner_before(__rhs); }
     533  
     534        template<typename _Tp, typename _Up>
     535          bool
     536          operator()(weak_ptr<_Tp> const& __lhs,
     537                     shared_ptr<_Up> const& __rhs) const
     538          { return __lhs.owner_before(__rhs); }
     539  
     540        template<typename _Tp, typename _Up>
     541          bool
     542          operator()(weak_ptr<_Tp> const& __lhs,
     543                     weak_ptr<_Up> const& __rhs) const
     544          { return __lhs.owner_before(__rhs); }
     545  
     546        typedef void is_transparent;
     547      };
     548  
     549     // C++14 20.8.2.6
     550     template<typename _Tp>
     551       inline bool
     552       atomic_is_lock_free(const shared_ptr<_Tp>* __p)
     553       { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }
     554  
     555     template<typename _Tp>
     556       shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p)
     557       { return std::atomic_load<_Tp>(__p); }
     558  
     559     template<typename _Tp>
     560       shared_ptr<_Tp>
     561       atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order __mo)
     562       { return std::atomic_load_explicit<_Tp>(__p, __mo); }
     563  
     564     template<typename _Tp>
     565       void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
     566       { return std::atomic_store<_Tp>(__p, __r); }
     567  
     568     template<typename _Tp>
     569       shared_ptr<_Tp>
     570       atomic_store_explicit(const shared_ptr<_Tp>* __p,
     571  			   shared_ptr<_Tp> __r,
     572  			   memory_order __mo)
     573       { return std::atomic_store_explicit<_Tp>(__p, __r, __mo); }
     574  
     575     template<typename _Tp>
     576       void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
     577       { return std::atomic_exchange<_Tp>(__p, __r); }
     578  
     579     template<typename _Tp>
     580       shared_ptr<_Tp>
     581       atomic_exchange_explicit(const shared_ptr<_Tp>* __p,
     582  			      shared_ptr<_Tp> __r,
     583  			      memory_order __mo)
     584       { return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); }
     585  
     586     template<typename _Tp>
     587       bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p,
     588  				       shared_ptr<_Tp>* __v,
     589  				       shared_ptr<_Tp> __w)
     590       { return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); }
     591  
     592     template<typename _Tp>
     593       bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p,
     594  					 shared_ptr<_Tp>* __v,
     595  					 shared_ptr<_Tp> __w)
     596       { return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); }
     597  
     598     template<typename _Tp>
     599       bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
     600  						shared_ptr<_Tp>* __v,
     601  						shared_ptr<_Tp> __w,
     602  						memory_order __success,
     603  						memory_order __failure)
     604       { return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w,
     605  							      __success,
     606  							      __failure); }
     607  
     608     template<typename _Tp>
     609       bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
     610  						  shared_ptr<_Tp>* __v,
     611  						  shared_ptr<_Tp> __w,
     612  						  memory_order __success,
     613  						  memory_order __failure)
     614       { return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w,
     615  								__success,
     616  								__failure); }
     617  
     618    //enable_shared_from_this
     619    template<typename _Tp>
     620      class enable_shared_from_this
     621      {
     622      protected:
     623        constexpr enable_shared_from_this() noexcept { }
     624  
     625        enable_shared_from_this(const enable_shared_from_this&) noexcept { }
     626  
     627        enable_shared_from_this&
     628        operator=(const enable_shared_from_this&) noexcept
     629        { return *this; }
     630  
     631        ~enable_shared_from_this() { }
     632  
     633      public:
     634        shared_ptr<_Tp>
     635        shared_from_this()
     636        { return shared_ptr<_Tp>(this->_M_weak_this); }
     637  
     638        shared_ptr<const _Tp>
     639        shared_from_this() const
     640        { return shared_ptr<const _Tp>(this->_M_weak_this); }
     641  
     642        weak_ptr<_Tp>
     643        weak_from_this() noexcept
     644        { return _M_weak_this; }
     645  
     646        weak_ptr<const _Tp>
     647        weak_from_this() const noexcept
     648        { return _M_weak_this; }
     649  
     650      private:
     651        template<typename _Tp1>
     652  	void
     653  	_M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
     654  	{ _M_weak_this._M_assign(__p, __n); }
     655  
     656        // Found by ADL when this is an associated class.
     657        friend const enable_shared_from_this*
     658        __expt_enable_shared_from_this_base(const enable_shared_from_this* __p)
     659        { return __p; }
     660  
     661        template<typename>
     662  	friend class shared_ptr;
     663  
     664        mutable weak_ptr<_Tp> _M_weak_this;
     665      };
     666  } // namespace fundamentals_v2
     667  } // namespace experimental
     668  
     669    /// std::hash specialization for shared_ptr.
     670    template<typename _Tp>
     671      struct hash<experimental::shared_ptr<_Tp>>
     672      : public __hash_base<size_t, experimental::shared_ptr<_Tp>>
     673      {
     674        size_t
     675        operator()(const experimental::shared_ptr<_Tp>& __s) const noexcept
     676        { return std::hash<_Tp*>()(__s.get()); }
     677      };
     678  
     679  _GLIBCXX_END_NAMESPACE_VERSION
     680  } // namespace std
     681  
     682  #endif // __cplusplus <= 201103L
     683  
     684  #endif // _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H