Home | History | Annotate | Line # | Download | only in bits
      1 // Experimental shared_ptr with array support -*- C++ -*-
      2 
      3 // Copyright (C) 2015-2022 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
    685