libstdc++
shared_ptr.h
Go to the documentation of this file.
00001 // Experimental shared_ptr with array support -*- C++ -*-
00002 
00003 // Copyright (C) 2015-2017 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file experimental/bits/shared_ptr.h
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{experimental/memory}
00028  */
00029 
00030 #ifndef _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H
00031 #define _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 1
00032 
00033 #pragma GCC system_header
00034 
00035 #if __cplusplus <= 201103L
00036 # include <bits/c++14_warning.h>
00037 #else
00038 
00039 #include <memory>
00040 #include <experimental/type_traits>
00041 
00042 namespace std _GLIBCXX_VISIBILITY(default)
00043 {
00044 namespace experimental
00045 {
00046 inline namespace fundamentals_v2
00047 {
00048 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00049 
00050   // 8.2.1
00051 
00052   template<typename _Tp> class shared_ptr;
00053   template<typename _Tp> class weak_ptr;
00054   template<typename _Tp> class enable_shared_from_this;
00055 
00056   template<typename _Yp, typename _Tp>
00057     constexpr bool __sp_compatible_v
00058       = std::__sp_compatible_with<_Yp*, _Tp*>::value;
00059 
00060   template<typename _Tp, typename _Yp>
00061     constexpr bool __sp_is_constructible_v
00062       = std::__sp_is_constructible<_Tp, _Yp>::value;
00063 
00064   template<typename _Tp>
00065     class shared_ptr : public __shared_ptr<_Tp>
00066     {
00067       using _Base_type = __shared_ptr<_Tp>;
00068 
00069     public:
00070       using element_type = typename _Base_type::element_type;
00071 
00072     private:
00073       // Constraint for construction from a pointer of type _Yp*:
00074       template<typename _Yp>
00075         using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
00076 
00077       template<typename _Tp1, typename _Res = void>
00078         using _Compatible
00079           = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
00080 
00081       template<typename _Tp1, typename _Del,
00082                typename _Ptr = typename unique_ptr<_Tp1, _Del>::pointer,
00083                typename _Res = void>
00084         using _UniqCompatible = enable_if_t<
00085           __sp_compatible_v<_Tp1, _Tp>
00086           && experimental::is_convertible_v<_Ptr, element_type*>,
00087           _Res>;
00088 
00089     public:
00090 
00091       // 8.2.1.1, shared_ptr constructors
00092       constexpr shared_ptr() noexcept = default;
00093 
00094       template<typename _Tp1, typename = _SafeConv<_Tp1>>
00095         explicit
00096         shared_ptr(_Tp1* __p) : _Base_type(__p)
00097         { _M_enable_shared_from_this_with(__p); }
00098 
00099       template<typename _Tp1, typename _Deleter, typename = _SafeConv<_Tp1>>
00100         shared_ptr(_Tp1* __p, _Deleter __d)
00101         : _Base_type(__p, __d)
00102         { _M_enable_shared_from_this_with(__p); }
00103 
00104       template<typename _Tp1, typename _Deleter, typename _Alloc,
00105                typename = _SafeConv<_Tp1>>
00106         shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
00107         : _Base_type(__p, __d, __a)
00108         { _M_enable_shared_from_this_with(__p); }
00109 
00110       template<typename _Deleter>
00111         shared_ptr(nullptr_t __p, _Deleter __d)
00112         : _Base_type(__p, __d) { }
00113 
00114       template<typename _Deleter, typename _Alloc>
00115         shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
00116         : _Base_type(__p, __d, __a) { }
00117 
00118       template<typename _Tp1>
00119         shared_ptr(const shared_ptr<_Tp1>& __r, element_type* __p) noexcept
00120         : _Base_type(__r, __p) { }
00121 
00122       shared_ptr(const shared_ptr& __r) noexcept
00123         : _Base_type(__r) { }
00124 
00125       template<typename _Tp1, typename = _Compatible<_Tp1>>
00126         shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
00127         : _Base_type(__r) { }
00128 
00129       shared_ptr(shared_ptr&& __r) noexcept
00130       : _Base_type(std::move(__r)) { }
00131 
00132       template<typename _Tp1, typename = _Compatible<_Tp1>>
00133         shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
00134         : _Base_type(std::move(__r)) { }
00135 
00136       template<typename _Tp1, typename = _Compatible<_Tp1>>
00137         explicit
00138         shared_ptr(const weak_ptr<_Tp1>& __r)
00139         : _Base_type(__r) { }
00140 
00141 #if _GLIBCXX_USE_DEPRECATED
00142       template<typename _Tp1, typename = _Compatible<_Tp1>>
00143         shared_ptr(std::auto_ptr<_Tp1>&& __r)
00144         : _Base_type(std::move(__r))
00145         { _M_enable_shared_from_this_with(static_cast<_Tp1*>(this->get())); }
00146 #endif
00147 
00148       template<typename _Tp1, typename _Del,
00149                typename = _UniqCompatible<_Tp1, _Del>>
00150         shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
00151         : _Base_type(std::move(__r))
00152         {
00153           // XXX assume conversion from __r.get() to this->get() to __elem_t*
00154           // is a round trip, which might not be true in all cases.
00155           using __elem_t = typename unique_ptr<_Tp1, _Del>::element_type;
00156           _M_enable_shared_from_this_with(static_cast<__elem_t*>(this->get()));
00157         }
00158 
00159       constexpr shared_ptr(nullptr_t __p)
00160       : _Base_type(__p) { }
00161 
00162       // C++14 §20.8.2.2
00163       ~shared_ptr() = default;
00164 
00165       // C++14 §20.8.2.3
00166       shared_ptr& operator=(const shared_ptr&) noexcept = default;
00167 
00168       template <typename _Tp1>
00169         _Compatible<_Tp1, shared_ptr&>
00170         operator=(const shared_ptr<_Tp1>& __r) noexcept
00171         {
00172           _Base_type::operator=(__r);
00173           return *this;
00174         }
00175 
00176       shared_ptr&
00177       operator=(shared_ptr&& __r) noexcept
00178       {
00179         _Base_type::operator=(std::move(__r));
00180         return *this;
00181       }
00182 
00183       template <typename _Tp1>
00184         _Compatible<_Tp1, shared_ptr&>
00185         operator=(shared_ptr<_Tp1>&& __r) noexcept
00186         {
00187           _Base_type::operator=(std::move(__r));
00188           return *this;
00189         }
00190 
00191 #if _GLIBCXX_USE_DEPRECATED
00192       template<typename _Tp1>
00193         _Compatible<_Tp1, shared_ptr&>
00194         operator=(std::auto_ptr<_Tp1>&& __r)
00195         {
00196           __shared_ptr<_Tp>::operator=(std::move(__r));
00197           return *this;
00198         }
00199 #endif
00200 
00201       template <typename _Tp1, typename _Del>
00202         _UniqCompatible<_Tp1, _Del, shared_ptr&>
00203         operator=(unique_ptr<_Tp1, _Del>&& __r)
00204         {
00205           _Base_type::operator=(std::move(__r));
00206           return *this;
00207         }
00208 
00209       // C++14 §20.8.2.2.4
00210       // swap & reset
00211       // 8.2.1.2 shared_ptr observers
00212       // in __shared_ptr
00213 
00214     private:
00215       template<typename _Alloc, typename... _Args>
00216         shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
00217                    _Args&&... __args)
00218         : _Base_type(__tag, __a, std::forward<_Args>(__args)...)
00219         { _M_enable_shared_from_this_with(this->get()); }
00220 
00221       template<typename _Tp1, typename _Alloc, typename... _Args>
00222         friend shared_ptr<_Tp1>
00223         allocate_shared(const _Alloc& __a, _Args&&...  __args);
00224 
00225       shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
00226       : _Base_type(__r, std::nothrow) { }
00227 
00228       friend class weak_ptr<_Tp>;
00229 
00230       template<typename _Yp>
00231         using __esft_base_t =
00232           decltype(__expt_enable_shared_from_this_base(std::declval<_Yp*>()));
00233 
00234       // Detect an accessible and unambiguous enable_shared_from_this base.
00235       template<typename _Yp, typename = void>
00236         struct __has_esft_base
00237         : false_type { };
00238 
00239       template<typename _Yp>
00240         struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
00241         : __bool_constant<!is_array_v<_Tp>> { };  // ignore base for arrays
00242 
00243       template<typename _Yp>
00244         typename enable_if<__has_esft_base<_Yp>::value>::type
00245         _M_enable_shared_from_this_with(const _Yp* __p) noexcept
00246         {
00247           if (auto __base = __expt_enable_shared_from_this_base(__p))
00248             {
00249               __base->_M_weak_this
00250                 = shared_ptr<_Yp>(*this, const_cast<_Yp*>(__p));
00251             }
00252         }
00253 
00254       template<typename _Yp>
00255         typename enable_if<!__has_esft_base<_Yp>::value>::type
00256         _M_enable_shared_from_this_with(const _Yp*) noexcept
00257         { }
00258     };
00259 
00260   // C++14 §20.8.2.2.7 //DOING
00261   template<typename _Tp1, typename _Tp2>
00262     bool operator==(const shared_ptr<_Tp1>& __a,
00263                     const shared_ptr<_Tp2>& __b) noexcept
00264     { return __a.get() == __b.get(); }
00265 
00266   template<typename _Tp>
00267     inline bool
00268     operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00269     { return !__a; }
00270 
00271   template<typename _Tp>
00272     inline bool
00273     operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00274     { return !__a; }
00275 
00276   template<typename _Tp1, typename _Tp2>
00277     inline bool
00278     operator!=(const shared_ptr<_Tp1>& __a,
00279                const shared_ptr<_Tp2>& __b) noexcept
00280     { return __a.get() != __b.get(); }
00281 
00282   template<typename _Tp>
00283     inline bool
00284     operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00285     { return (bool)__a; }
00286 
00287   template<typename _Tp>
00288     inline bool
00289     operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00290     { return (bool)__a; }
00291 
00292   template<typename _Tp1, typename _Tp2>
00293     inline bool
00294     operator<(const shared_ptr<_Tp1>& __a,
00295               const shared_ptr<_Tp2>& __b) noexcept
00296     {
00297       using __elem_t1 = typename shared_ptr<_Tp1>::element_type;
00298       using __elem_t2 = typename shared_ptr<_Tp2>::element_type;
00299       using _CT = common_type_t<__elem_t1*, __elem_t2*>;
00300       return std::less<_CT>()(__a.get(), __b.get());
00301     }
00302 
00303   template<typename _Tp>
00304     inline bool
00305     operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00306     {
00307       using __elem_t = typename shared_ptr<_Tp>::element_type;
00308       return std::less<__elem_t*>()(__a.get(), nullptr);
00309     }
00310 
00311   template<typename _Tp>
00312     inline bool
00313     operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00314     {
00315       using __elem_t = typename shared_ptr<_Tp>::element_type;
00316       return std::less<__elem_t*>()(nullptr, __a.get());
00317     }
00318 
00319   template<typename _Tp1, typename _Tp2>
00320     inline bool
00321     operator<=(const shared_ptr<_Tp1>& __a,
00322                const shared_ptr<_Tp2>& __b) noexcept
00323     { return !(__b < __a); }
00324 
00325   template<typename _Tp>
00326     inline bool
00327     operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00328     { return !(nullptr < __a); }
00329 
00330   template<typename _Tp>
00331     inline bool
00332     operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00333     { return !(__a < nullptr); }
00334 
00335   template<typename _Tp1, typename _Tp2>
00336     inline bool
00337     operator>(const shared_ptr<_Tp1>& __a,
00338               const shared_ptr<_Tp2>& __b) noexcept
00339     { return (__b < __a); }
00340 
00341   template<typename _Tp>
00342     inline bool
00343     operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00344     {
00345       using __elem_t = typename shared_ptr<_Tp>::element_type;
00346       return std::less<__elem_t*>()(nullptr, __a.get());
00347     }
00348 
00349   template<typename _Tp>
00350     inline bool
00351     operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00352     {
00353       using __elem_t = typename shared_ptr<_Tp>::element_type;
00354       return std::less<__elem_t*>()(__a.get(), nullptr);
00355     }
00356 
00357   template<typename _Tp1, typename _Tp2>
00358     inline bool
00359     operator>=(const shared_ptr<_Tp1>& __a,
00360                const shared_ptr<_Tp2>& __b) noexcept
00361     { return !(__a < __b); }
00362 
00363   template<typename _Tp>
00364     inline bool
00365     operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00366     { return !(__a < nullptr); }
00367 
00368   template<typename _Tp>
00369     inline bool
00370     operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00371     { return !(nullptr < __a); }
00372 
00373   // C++14 §20.8.2.2.8
00374   template<typename _Tp>
00375     inline void
00376     swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
00377     { __a.swap(__b); }
00378 
00379   // 8.2.1.3, shared_ptr casts
00380   template<typename _Tp, typename _Tp1>
00381     inline shared_ptr<_Tp>
00382     static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
00383     {
00384       using __elem_t = typename shared_ptr<_Tp>::element_type;
00385       return shared_ptr<_Tp>(__r, static_cast<__elem_t*>(__r.get()));
00386     }
00387 
00388   template<typename _Tp, typename _Tp1>
00389     inline shared_ptr<_Tp>
00390     dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
00391     {
00392       using __elem_t = typename shared_ptr<_Tp>::element_type;
00393       if (_Tp* __p = dynamic_cast<__elem_t*>(__r.get()))
00394         return shared_ptr<_Tp>(__r, __p);
00395       return shared_ptr<_Tp>();
00396     }
00397 
00398   template<typename _Tp, typename _Tp1>
00399     inline shared_ptr<_Tp>
00400     const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
00401     {
00402       using __elem_t = typename shared_ptr<_Tp>::element_type;
00403       return shared_ptr<_Tp>(__r, const_cast<__elem_t*>(__r.get()));
00404     }
00405 
00406   template<typename _Tp, typename _Tp1>
00407     inline shared_ptr<_Tp>
00408     reinterpret_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
00409     {
00410       using __elem_t = typename shared_ptr<_Tp>::element_type;
00411       return shared_ptr<_Tp>(__r, reinterpret_cast<__elem_t*>(__r.get()));
00412     }
00413 
00414   // C++14 §20.8.2.3
00415   template<typename _Tp>
00416     class weak_ptr : public __weak_ptr<_Tp>
00417     {
00418       template<typename _Tp1, typename _Res = void>
00419         using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
00420 
00421       using _Base_type = __weak_ptr<_Tp>;
00422 
00423      public:
00424        constexpr weak_ptr() noexcept = default;
00425 
00426        template<typename _Tp1, typename = _Compatible<_Tp1>>
00427          weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
00428          : _Base_type(__r) { }
00429 
00430        weak_ptr(const weak_ptr&) noexcept = default;
00431 
00432        template<typename _Tp1, typename = _Compatible<_Tp1>>
00433          weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
00434          : _Base_type(__r) { }
00435 
00436        weak_ptr(weak_ptr&&) noexcept = default;
00437 
00438        template<typename _Tp1, typename = _Compatible<_Tp1>>
00439          weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
00440          : _Base_type(std::move(__r)) { }
00441 
00442        weak_ptr&
00443        operator=(const weak_ptr& __r) noexcept = default;
00444 
00445        template<typename _Tp1>
00446          _Compatible<_Tp1, weak_ptr&>
00447          operator=(const weak_ptr<_Tp1>& __r) noexcept
00448          {
00449            this->_Base_type::operator=(__r);
00450            return *this;
00451          }
00452 
00453        template<typename _Tp1>
00454          _Compatible<_Tp1, weak_ptr&>
00455          operator=(const shared_ptr<_Tp1>& __r) noexcept
00456          {
00457            this->_Base_type::operator=(__r);
00458            return *this;
00459          }
00460 
00461        weak_ptr&
00462        operator=(weak_ptr&& __r) noexcept = default;
00463 
00464        template<typename _Tp1>
00465          _Compatible<_Tp1, weak_ptr&>
00466          operator=(weak_ptr<_Tp1>&& __r) noexcept
00467          {
00468            this->_Base_type::operator=(std::move(__r));
00469            return *this;
00470          }
00471 
00472        shared_ptr<_Tp>
00473        lock() const noexcept
00474        { return shared_ptr<_Tp>(*this, std::nothrow); }
00475 
00476        friend class enable_shared_from_this<_Tp>;
00477     };
00478 
00479   // C++14 §20.8.2.3.6
00480   template<typename _Tp>
00481     inline void
00482     swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
00483     { __a.swap(__b); }
00484 
00485   /// C++14 §20.8.2.2.10
00486   template<typename _Del, typename _Tp>
00487     inline _Del*
00488     get_deleter(const shared_ptr<_Tp>& __p) noexcept
00489     { return std::get_deleter<_Del>(__p); }
00490 
00491   // C++14 §20.8.2.2.11
00492   template<typename _Ch, typename _Tr, typename _Tp>
00493     inline std::basic_ostream<_Ch, _Tr>&
00494     operator<<(std::basic_ostream<_Ch, _Tr>& __os, const shared_ptr<_Tp>& __p)
00495     {
00496       __os << __p.get();
00497       return __os;
00498     }
00499 
00500   // C++14 §20.8.2.4
00501   template<typename _Tp = void> class owner_less;
00502 
00503    /// Partial specialization of owner_less for shared_ptr.
00504   template<typename _Tp>
00505     struct owner_less<shared_ptr<_Tp>>
00506     : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
00507     { };
00508 
00509   /// Partial specialization of owner_less for weak_ptr.
00510   template<typename _Tp>
00511     struct owner_less<weak_ptr<_Tp>>
00512     : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
00513     { };
00514 
00515   template<>
00516     class owner_less<void>
00517     {
00518       template<typename _Tp, typename _Up>
00519         bool
00520         operator()(shared_ptr<_Tp> const& __lhs,
00521                    shared_ptr<_Up> const& __rhs) const
00522         { return __lhs.owner_before(__rhs); }
00523 
00524       template<typename _Tp, typename _Up>
00525         bool
00526         operator()(shared_ptr<_Tp> const& __lhs,
00527                    weak_ptr<_Up> const& __rhs) const
00528         { return __lhs.owner_before(__rhs); }
00529 
00530       template<typename _Tp, typename _Up>
00531         bool
00532         operator()(weak_ptr<_Tp> const& __lhs,
00533                    shared_ptr<_Up> const& __rhs) const
00534         { return __lhs.owner_before(__rhs); }
00535 
00536       template<typename _Tp, typename _Up>
00537         bool
00538         operator()(weak_ptr<_Tp> const& __lhs,
00539                    weak_ptr<_Up> const& __rhs) const
00540         { return __lhs.owner_before(__rhs); }
00541 
00542       typedef void is_transparent;
00543     };
00544 
00545    // C++14 §20.8.2.6
00546    template<typename _Tp>
00547      inline bool
00548      atomic_is_lock_free(const shared_ptr<_Tp>* __p)
00549      { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }
00550 
00551    template<typename _Tp>
00552      shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p)
00553      { return std::atomic_load<_Tp>(__p); }
00554 
00555    template<typename _Tp>
00556      shared_ptr<_Tp>
00557      atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order __mo)
00558      { return std::atomic_load_explicit<_Tp>(__p, __mo); }
00559 
00560    template<typename _Tp>
00561      void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
00562      { return std::atomic_store<_Tp>(__p, __r); }
00563 
00564    template<typename _Tp>
00565      shared_ptr<_Tp>
00566      atomic_store_explicit(const shared_ptr<_Tp>* __p,
00567                            shared_ptr<_Tp> __r,
00568                            memory_order __mo)
00569      { return std::atomic_store_explicit<_Tp>(__p, __r, __mo); }
00570 
00571    template<typename _Tp>
00572      void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
00573      { return std::atomic_exchange<_Tp>(__p, __r); }
00574 
00575    template<typename _Tp>
00576      shared_ptr<_Tp>
00577      atomic_exchange_explicit(const shared_ptr<_Tp>* __p,
00578                               shared_ptr<_Tp> __r,
00579                               memory_order __mo)
00580      { return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); }
00581 
00582    template<typename _Tp>
00583      bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p,
00584                                        shared_ptr<_Tp>* __v,
00585                                        shared_ptr<_Tp> __w)
00586      { return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); }
00587 
00588    template<typename _Tp>
00589      bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p,
00590                                          shared_ptr<_Tp>* __v,
00591                                          shared_ptr<_Tp> __w)
00592      { return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); }
00593 
00594    template<typename _Tp>
00595      bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
00596                                                 shared_ptr<_Tp>* __v,
00597                                                 shared_ptr<_Tp> __w,
00598                                                 memory_order __success,
00599                                                 memory_order __failure)
00600      { return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w,
00601                                                               __success,
00602                                                               __failure); }
00603 
00604    template<typename _Tp>
00605      bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
00606                                                   shared_ptr<_Tp>* __v,
00607                                                   shared_ptr<_Tp> __w,
00608                                                   memory_order __success,
00609                                                   memory_order __failure)
00610      { return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w,
00611                                                                 __success,
00612                                                                 __failure); }
00613 
00614   //enable_shared_from_this
00615   template<typename _Tp>
00616     class enable_shared_from_this
00617     {
00618     protected:
00619       constexpr enable_shared_from_this() noexcept { }
00620 
00621       enable_shared_from_this(const enable_shared_from_this&) noexcept { }
00622 
00623       enable_shared_from_this&
00624       operator=(const enable_shared_from_this&) noexcept
00625       { return *this; }
00626 
00627       ~enable_shared_from_this() { }
00628 
00629     public:
00630       shared_ptr<_Tp>
00631       shared_from_this()
00632       { return shared_ptr<_Tp>(this->_M_weak_this); }
00633 
00634       shared_ptr<const _Tp>
00635       shared_from_this() const
00636       { return shared_ptr<const _Tp>(this->_M_weak_this); }
00637 
00638       weak_ptr<_Tp>
00639       weak_from_this() noexcept
00640       { return _M_weak_this; }
00641 
00642       weak_ptr<const _Tp>
00643       weak_from_this() const noexcept
00644       { return _M_weak_this; }
00645 
00646     private:
00647       template<typename _Tp1>
00648         void
00649         _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
00650         { _M_weak_this._M_assign(__p, __n); }
00651 
00652       // Found by ADL when this is an associated class.
00653       friend const enable_shared_from_this*
00654       __expt_enable_shared_from_this_base(const enable_shared_from_this* __p)
00655       { return __p; }
00656 
00657       template<typename>
00658         friend class shared_ptr;
00659 
00660       mutable weak_ptr<_Tp> _M_weak_this;
00661     };
00662 
00663 _GLIBCXX_END_NAMESPACE_VERSION
00664 } // namespace fundamentals_v2
00665 } // namespace experimental
00666 
00667 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00668 
00669   /// std::hash specialization for shared_ptr.
00670   template<typename _Tp>
00671     struct hash<experimental::shared_ptr<_Tp>>
00672     : public __hash_base<size_t, experimental::shared_ptr<_Tp>>
00673     {
00674       size_t
00675       operator()(const experimental::shared_ptr<_Tp>& __s) const noexcept
00676       { return std::hash<_Tp*>()(__s.get()); }
00677     };
00678 
00679 _GLIBCXX_END_NAMESPACE_VERSION
00680 } // namespace std
00681 
00682 #endif // __cplusplus <= 201103L
00683 
00684 #endif // _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H