libstdc++
shared_ptr.h
Go to the documentation of this file.
00001 // Experimental shared_ptr with array support -*- C++ -*-
00002 
00003 // Copyright (C) 2015-2016 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   template<typename _Tp> class enable_shared_from_this;
00050 _GLIBCXX_END_NAMESPACE_VERSION
00051 } // namespace fundamentals_v2
00052 } // namespace experimental
00053 
00054 #define __cpp_lib_experimental_shared_ptr_arrays 201406
00055 
00056 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00057 
00058   /*
00059    * The specification of std::experimental::shared_ptr is slightly different
00060    * to std::shared_ptr (specifically in terms of "compatible" pointers) so
00061    * to implement std::experimental::shared_ptr without too much duplication
00062    * we make it derive from a partial specialization of std::__shared_ptr
00063    * using a special tag type, __libfund_v1.
00064    *
00065    * There are two partial specializations for the tag type, supporting the
00066    * different interfaces of the array and non-array forms.
00067   */
00068 
00069   template <typename _Tp, bool = is_array<_Tp>::value>
00070     struct __libfund_v1 { using type = _Tp; };
00071 
00072   // Partial specialization for base class of experimental::shared_ptr<T>
00073   // (i.e. the non-array form of experimental::shared_ptr)
00074   template<typename _Tp, _Lock_policy _Lp>
00075     class __shared_ptr<__libfund_v1<_Tp, false>, _Lp>
00076     : private __shared_ptr<_Tp, _Lp>
00077     {
00078       // For non-arrays, Y* is compatible with T* if Y* is convertible to T*.
00079       template<typename _Yp, typename _Res = void>
00080         using _Compatible
00081           = enable_if_t<experimental::is_convertible_v<_Yp*, _Tp*>, _Res>;
00082 
00083       template<typename _Yp, typename _Del,
00084                typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer,
00085                typename _Res = void>
00086         using _UniqCompatible = enable_if_t<
00087           experimental::is_convertible_v<_Yp*, _Tp*>
00088           && experimental::is_convertible_v<_Ptr, _Tp*>,
00089           _Res>;
00090 
00091       using _Base_type = __shared_ptr<_Tp>;
00092 
00093       _Base_type&  _M_get_base() { return *this; }
00094       const _Base_type&  _M_get_base() const { return *this; }
00095 
00096     public:
00097       using element_type = _Tp;
00098 
00099       constexpr __shared_ptr() noexcept = default;
00100 
00101       template<typename _Tp1, typename = _Compatible<_Tp1>>
00102         explicit
00103         __shared_ptr(_Tp1* __p)
00104         : _Base_type(__p)
00105         { }
00106 
00107       template<typename _Tp1, typename _Deleter, typename = _Compatible<_Tp1>>
00108         __shared_ptr(_Tp1* __p, _Deleter __d)
00109         : _Base_type(__p, __d)
00110         { }
00111 
00112       template<typename _Tp1, typename _Deleter, typename _Alloc,
00113                typename = _Compatible<_Tp1>>
00114         __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
00115         : _Base_type(__p, __d, __a)
00116         { }
00117 
00118       template<typename _Deleter>
00119         __shared_ptr(nullptr_t __p, _Deleter __d)
00120         : _Base_type(__p, __d)
00121         { }
00122 
00123       template<typename _Deleter, typename _Alloc>
00124         __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
00125         : _Base_type(__p, __d, __a)
00126         { }
00127 
00128       template<typename _Tp1>
00129         __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r,
00130                      element_type* __p) noexcept
00131         : _Base_type(__r._M_get_base(), __p)
00132         { }
00133 
00134       __shared_ptr(const __shared_ptr&) noexcept = default;
00135       __shared_ptr(__shared_ptr&&) noexcept = default;
00136       __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
00137       __shared_ptr& operator=(__shared_ptr&&) noexcept = default;
00138       ~__shared_ptr() = default;
00139 
00140       template<typename _Tp1, typename = _Compatible<_Tp1>>
00141         __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
00142         : _Base_type(__r._M_get_base())
00143         { }
00144 
00145       template<typename _Tp1, typename = _Compatible<_Tp1>>
00146         __shared_ptr(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
00147         : _Base_type(std::move((__r._M_get_base())))
00148         { }
00149 
00150       template<typename _Tp1, typename = _Compatible<_Tp1>>
00151         explicit
00152         __shared_ptr(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r)
00153         : _Base_type(__r._M_get_base())
00154         { }
00155 
00156       template<typename _Tp1, typename _Del,
00157                typename = _UniqCompatible<_Tp1, _Del>>
00158         __shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
00159         : _Base_type(std::move(__r))
00160         { }
00161 
00162 #if _GLIBCXX_USE_DEPRECATED
00163       // Postcondition: use_count() == 1 and __r.get() == 0
00164       template<typename _Tp1, typename = _Compatible<_Tp1>>
00165         __shared_ptr(std::auto_ptr<_Tp1>&& __r)
00166         : _Base_type(std::move(__r))
00167         { }
00168 #endif
00169 
00170       constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
00171 
00172       // reset
00173       void
00174       reset() noexcept
00175       { __shared_ptr(nullptr).swap(*this); }
00176 
00177       template<typename _Tp1>
00178         _Compatible<_Tp1>
00179         reset(_Tp1* __p)
00180         {
00181           _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != get());
00182           __shared_ptr(__p).swap(*this);
00183         }
00184 
00185       template<typename _Tp1, typename _Deleter>
00186         _Compatible<_Tp1>
00187         reset(_Tp1* __p, _Deleter __d)
00188         { __shared_ptr(__p, __d).swap(*this); }
00189 
00190       template<typename _Tp1, typename _Deleter, typename _Alloc>
00191         _Compatible<_Tp1>
00192         reset(_Tp1* __p, _Deleter __d, _Alloc __a)
00193         { __shared_ptr(__p, __d, std::move(__a)).swap(*this); }
00194 
00195       using _Base_type::operator*;
00196       using _Base_type::operator->;
00197 
00198       template<typename _Tp1>
00199         _Compatible<_Tp1, __shared_ptr&>
00200         operator=(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
00201         {
00202           _Base_type::operator=(__r._M_get_base());
00203           return *this;
00204         }
00205 
00206       template<class _Tp1>
00207         _Compatible<_Tp1, __shared_ptr&>
00208         operator=(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
00209         {
00210           _Base_type::operator=(std::move(__r._M_get_base()));
00211           return *this;
00212         }
00213 
00214       template<typename _Tp1, typename _Del>
00215         _UniqCompatible<_Tp1, _Del, __shared_ptr&>
00216         operator=(unique_ptr<_Tp1, _Del>&& __r)
00217         {
00218           _Base_type::operator=(std::move(__r));
00219           return *this;
00220         }
00221 
00222 #if _GLIBCXX_USE_DEPRECATED
00223       template<typename _Tp1>
00224         _Compatible<_Tp1, __shared_ptr&>
00225         operator=(std::auto_ptr<_Tp1>&& __r)
00226         {
00227           _Base_type::operator=(std::move(__r));
00228           return *this;
00229         }
00230 #endif
00231 
00232       void
00233       swap(__shared_ptr& __other) noexcept
00234       { _Base_type::swap(__other); }
00235 
00236       template<typename _Tp1>
00237         bool
00238         owner_before(__shared_ptr<__libfund_v1<_Tp1>, _Lp> const& __rhs) const
00239         { return _Base_type::owner_before(__rhs._M_get_base()); }
00240 
00241       template<typename _Tp1>
00242         bool
00243         owner_before(__weak_ptr<__libfund_v1<_Tp1>, _Lp> const& __rhs) const
00244         { return _Base_type::owner_before(__rhs._M_get_base()); }
00245 
00246       using _Base_type::operator bool;
00247       using _Base_type::get;
00248       using _Base_type::unique;
00249       using _Base_type::use_count;
00250 
00251     protected:
00252 
00253       // make_shared not yet support for shared_ptr_arrays
00254       //template<typename _Alloc, typename... _Args>
00255       //  __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
00256       //                     _Args&&... __args)
00257       //        : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
00258       //                                std::forward<_Args>(__args)...)
00259       //        {
00260       //          void* __p = _M_refcount._M_get_deleter(typeid(__tag));
00261       //          _M_ptr = static_cast<_Tp*>(__p);
00262       //        }
00263 
00264       // __weak_ptr::lock()
00265       __shared_ptr(const __weak_ptr<__libfund_v1<_Tp>, _Lp>& __r,
00266                    std::nothrow_t)
00267       : _Base_type(__r._M_get_base(), std::nothrow)
00268       { }
00269 
00270     private:
00271       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
00272       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
00273 
00274       // TODO
00275       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
00276         friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
00277     };
00278 
00279   // Helper traits for shared_ptr of array:
00280 
00281   // Trait that tests if Y* is compatible with T*, for shared_ptr purposes.
00282   template<typename _Yp, typename _Tp>
00283     struct __sp_compatible
00284     : is_convertible<_Yp*, _Tp*>::type
00285     { };
00286 
00287   template<size_t _Nm, typename _Tp>
00288     struct __sp_compatible<_Tp[_Nm], _Tp[]>
00289     : true_type
00290     { };
00291 
00292   template<size_t _Nm, typename _Tp>
00293     struct __sp_compatible<_Tp[_Nm], const _Tp[]>
00294     : true_type
00295     { };
00296 
00297   template<typename _Yp, typename _Tp>
00298     constexpr bool __sp_compatible_v
00299       = __sp_compatible<_Yp, _Tp>::value;
00300 
00301   // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N].
00302   template<typename _Up, size_t _Nm, typename _Yp, typename = void>
00303     struct __sp_is_constructible_arrN
00304     : false_type
00305     { };
00306 
00307   template<typename _Up, size_t _Nm, typename _Yp>
00308     struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
00309     : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
00310     { };
00311 
00312   // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[].
00313   template<typename _Up, typename _Yp, typename = void>
00314     struct __sp_is_constructible_arr
00315     : false_type
00316     { };
00317 
00318   template<typename _Up, typename _Yp>
00319     struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
00320     : is_convertible<_Yp(*)[], _Up(*)[]>::type
00321     { };
00322 
00323   // Trait to check if shared_ptr<T> can be constructed from Y*.
00324   template<typename _Tp, typename _Yp>
00325     struct __sp_is_constructible;
00326 
00327   // When T is U[N], Y(*)[N] shall be convertible to T*;
00328   template<typename _Up, size_t _Nm, typename _Yp>
00329     struct __sp_is_constructible<_Up[_Nm], _Yp>
00330     : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
00331     { };
00332 
00333   // when T is U[], Y(*)[] shall be convertible to T*;
00334   template<typename _Up, typename _Yp>
00335     struct __sp_is_constructible<_Up[], _Yp>
00336     : __sp_is_constructible_arr<_Up, _Yp>::type
00337     { };
00338 
00339   // otherwise, Y* shall be convertible to T*.
00340   template<typename _Tp, typename _Yp>
00341     struct __sp_is_constructible
00342     : is_convertible<_Yp*, _Tp*>::type
00343     { };
00344 
00345   template<typename _Tp, typename _Yp>
00346     constexpr bool __sp_is_constructible_v
00347       = __sp_is_constructible<_Tp, _Yp>::value;
00348 
00349 
00350   // Partial specialization for base class of experimental::shared_ptr<T[N]>
00351   // and experimental::shared_ptr<T[]> (i.e. the array forms).
00352   template<typename _Tp, _Lock_policy _Lp>
00353     class __shared_ptr<__libfund_v1<_Tp, true>, _Lp>
00354     : private __shared_ptr<remove_extent_t<_Tp>, _Lp>
00355     {
00356     public:
00357       using element_type = remove_extent_t<_Tp>;
00358 
00359     private:
00360       struct _Array_deleter
00361       {
00362         void
00363         operator()(element_type const *__p) const
00364         { delete [] __p; }
00365       };
00366 
00367       // Constraint for constructing/resetting with a pointer of type _Yp*:
00368       template<typename _Yp>
00369         using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
00370 
00371       // Constraint for constructing/assigning from smart_pointer<_Tp1>:
00372       template<typename _Tp1, typename _Res = void>
00373         using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
00374 
00375       // Constraint for constructing/assigning from unique_ptr<_Tp1, _Del>:
00376       template<typename _Tp1, typename _Del,
00377                typename _Ptr = typename unique_ptr<_Tp1, _Del>::pointer,
00378                typename _Res = void>
00379         using _UniqCompatible = enable_if_t<
00380           __sp_compatible_v<_Tp1, _Tp>
00381           && experimental::is_convertible_v<_Ptr, element_type*>,
00382           _Res>;
00383 
00384       using _Base_type = __shared_ptr<element_type>;
00385 
00386       _Base_type&  _M_get_base() { return *this; }
00387       const _Base_type&  _M_get_base() const { return *this; }
00388 
00389     public:
00390       constexpr __shared_ptr() noexcept
00391       : _Base_type()
00392       { }
00393 
00394       template<typename _Tp1, typename = _SafeConv<_Tp1>>
00395         explicit
00396         __shared_ptr(_Tp1* __p)
00397         : _Base_type(__p, _Array_deleter())
00398         { }
00399 
00400       template<typename _Tp1, typename _Deleter, typename = _SafeConv<_Tp1>>
00401         __shared_ptr(_Tp1* __p, _Deleter __d)
00402         : _Base_type(__p, __d)
00403         { }
00404 
00405       template<typename _Tp1, typename _Deleter, typename _Alloc,
00406                typename = _SafeConv<_Tp1>>
00407         __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
00408         : _Base_type(__p, __d, __a)
00409         { }
00410 
00411       template<typename _Deleter>
00412         __shared_ptr(nullptr_t __p, _Deleter __d)
00413         : _Base_type(__p, __d)
00414         { }
00415 
00416       template<typename _Deleter, typename _Alloc>
00417         __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
00418         : _Base_type(__p, __d, __a)
00419         { }
00420 
00421       template<typename _Tp1>
00422         __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r,
00423                      element_type* __p) noexcept
00424         : _Base_type(__r._M_get_base(), __p)
00425         { }
00426 
00427       __shared_ptr(const __shared_ptr&) noexcept = default;
00428       __shared_ptr(__shared_ptr&&) noexcept = default;
00429       __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
00430       __shared_ptr& operator=(__shared_ptr&&) noexcept = default;
00431       ~__shared_ptr() = default;
00432 
00433       template<typename _Tp1, typename = _Compatible<_Tp1>>
00434         __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
00435         : _Base_type(__r._M_get_base())
00436         { }
00437 
00438       template<typename _Tp1, typename = _Compatible<_Tp1>>
00439         __shared_ptr(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
00440         : _Base_type(std::move((__r._M_get_base())))
00441         { }
00442 
00443       template<typename _Tp1, typename = _Compatible<_Tp1>>
00444         explicit
00445         __shared_ptr(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r)
00446         : _Base_type(__r._M_get_base())
00447         { }
00448 
00449       template<typename _Tp1, typename _Del,
00450                typename = _UniqCompatible<_Tp1, _Del>>
00451         __shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
00452         : _Base_type(std::move(__r))
00453         { }
00454 
00455 #if _GLIBCXX_USE_DEPRECATED
00456       // Postcondition: use_count() == 1 and __r.get() == 0
00457       template<typename _Tp1, typename = _Compatible<_Tp1>>
00458         __shared_ptr(auto_ptr<_Tp1>&& __r)
00459         : _Base_type(std::move(__r))
00460         { }
00461 #endif
00462 
00463       constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
00464 
00465       // reset
00466       void
00467       reset() noexcept
00468       { __shared_ptr(nullptr).swap(*this); }
00469 
00470       template<typename _Tp1>
00471         _SafeConv<_Tp1>
00472         reset(_Tp1* __p)
00473         {
00474           _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != get());
00475           __shared_ptr(__p, _Array_deleter()).swap(*this);
00476         }
00477 
00478       template<typename _Tp1, typename _Deleter>
00479         _SafeConv<_Tp1>
00480         reset(_Tp1* __p, _Deleter __d)
00481         { __shared_ptr(__p, __d).swap(*this); }
00482 
00483       template<typename _Tp1, typename _Deleter, typename _Alloc>
00484         _SafeConv<_Tp1>
00485         reset(_Tp1* __p, _Deleter __d, _Alloc __a)
00486         { __shared_ptr(__p, __d, std::move(__a)).swap(*this); }
00487 
00488       element_type&
00489       operator[](ptrdiff_t i) const noexcept
00490       {
00491         _GLIBCXX_DEBUG_ASSERT(get() != 0 && i >= 0);
00492         return get()[i];
00493       }
00494 
00495       template<typename _Tp1>
00496         _Compatible<_Tp1, __shared_ptr&>
00497         operator=(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
00498         {
00499           _Base_type::operator=(__r._M_get_base());
00500           return *this;
00501         }
00502 
00503       template<class _Tp1>
00504         _Compatible<_Tp1, __shared_ptr&>
00505         operator=(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
00506         {
00507           _Base_type::operator=(std::move(__r._M_get_base()));
00508           return *this;
00509         }
00510 
00511       template<typename _Tp1, typename _Del>
00512         _UniqCompatible<_Tp1, _Del, __shared_ptr&>
00513         operator=(unique_ptr<_Tp1, _Del>&& __r)
00514         {
00515           _Base_type::operator=(std::move(__r));
00516           return *this;
00517         }
00518 
00519 #if _GLIBCXX_USE_DEPRECATED
00520       template<typename _Tp1>
00521         _Compatible<_Tp1, __shared_ptr&>
00522         operator=(auto_ptr<_Tp1>&& __r)
00523         {
00524           _Base_type::operator=(std::move(__r));
00525           return *this;
00526         }
00527 #endif
00528 
00529       void
00530       swap(__shared_ptr& __other) noexcept
00531       { _Base_type::swap(__other); }
00532 
00533       template<typename _Tp1>
00534         bool
00535         owner_before(__shared_ptr<__libfund_v1<_Tp1>, _Lp> const& __rhs) const
00536         { return _Base_type::owner_before(__rhs._M_get_base()); }
00537 
00538       template<typename _Tp1>
00539         bool
00540         owner_before(__weak_ptr<__libfund_v1<_Tp1>, _Lp> const& __rhs) const
00541         { return _Base_type::owner_before(__rhs._M_get_base()); }
00542 
00543       using _Base_type::operator bool;
00544       using _Base_type::get;
00545       using _Base_type::unique;
00546       using _Base_type::use_count;
00547 
00548     protected:
00549 
00550       // make_shared not yet support for shared_ptr_arrays
00551       //template<typename _Alloc, typename... _Args>
00552       //  __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
00553       //                     _Args&&... __args)
00554       //        : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
00555       //                                std::forward<_Args>(__args)...)
00556       //        {
00557       //          void* __p = _M_refcount._M_get_deleter(typeid(__tag));
00558       //          _M_ptr = static_cast<_Tp*>(__p);
00559       //        }
00560 
00561       // __weak_ptr::lock()
00562       __shared_ptr(const __weak_ptr<__libfund_v1<_Tp>, _Lp>& __r,
00563                    std::nothrow_t)
00564       : _Base_type(__r._M_get_base(), std::nothrow)
00565       { }
00566 
00567     private:
00568       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
00569       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
00570 
00571       // TODO
00572       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
00573         friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
00574     };
00575 
00576   // weak_ptr specialization for __shared_ptr array
00577   template<typename _Tp, _Lock_policy _Lp>
00578     class __weak_ptr<__libfund_v1<_Tp>, _Lp>
00579     : __weak_ptr<remove_extent_t<_Tp>, _Lp>
00580     {
00581       template<typename _Tp1, typename _Res = void>
00582         using _Compatible
00583           = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
00584 
00585       using _Base_type = __weak_ptr<remove_extent_t<_Tp>>;
00586 
00587       _Base_type&  _M_get_base() { return *this; }
00588       const _Base_type&  _M_get_base() const { return *this; }
00589 
00590     public:
00591       using element_type = remove_extent_t<_Tp>;
00592 
00593       constexpr __weak_ptr() noexcept
00594       : _Base_type()
00595       { }
00596 
00597       __weak_ptr(const __weak_ptr&) noexcept = default;
00598 
00599       ~__weak_ptr() = default;
00600 
00601       template<typename _Tp1, typename = _Compatible<_Tp1>>
00602         __weak_ptr(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
00603         : _Base_type(__r._M_get_base())
00604         { }
00605 
00606       template<typename _Tp1, typename = _Compatible<_Tp1>>
00607         __weak_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
00608         : _Base_type(__r._M_get_base())
00609         { }
00610 
00611       __weak_ptr(__weak_ptr&& __r) noexcept
00612       : _Base_type(std::move(__r))
00613       { }
00614 
00615       template<typename _Tp1, typename = _Compatible<_Tp1>>
00616         __weak_ptr(__weak_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
00617         : _Base_type(std::move(__r._M_get_base()))
00618         { }
00619 
00620       __weak_ptr&
00621       operator=(const __weak_ptr& __r) noexcept = default;
00622 
00623       template<typename _Tp1>
00624         _Compatible<_Tp1, __weak_ptr&>
00625         operator=(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
00626         {
00627           this->_Base_type::operator=(__r._M_get_base());
00628           return *this;
00629         }
00630 
00631       template<typename _Tp1>
00632         _Compatible<_Tp1, __weak_ptr&>
00633         operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
00634         {
00635           this->_Base_type::operator=(__r._M_get_base());
00636           return *this;
00637         }
00638 
00639       __weak_ptr&
00640       operator=(__weak_ptr&& __r) noexcept
00641       {
00642         this->_Base_type::operator=(std::move(__r));
00643         return *this;
00644       }
00645 
00646       template<typename _Tp1>
00647         _Compatible<_Tp1, __weak_ptr&>
00648         operator=(__weak_ptr<_Tp1, _Lp>&& __r) noexcept
00649         {
00650           this->_Base_type::operator=(std::move(__r._M_get_base()));
00651           return *this;
00652         }
00653 
00654       void
00655       swap(__weak_ptr& __other) noexcept
00656       { this->_Base_type::swap(__other); }
00657 
00658       template<typename _Tp1>
00659         bool
00660         owner_before(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __rhs) const
00661         { return _Base_type::owner_before(__rhs._M_get_base()); }
00662 
00663       template<typename _Tp1>
00664         bool
00665         owner_before(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __rhs) const
00666         { return _Base_type::owner_before(__rhs._M_get_base()); }
00667 
00668       __shared_ptr<__libfund_v1<_Tp>, _Lp>
00669       lock() const noexcept  // should not be element_type
00670       { return __shared_ptr<__libfund_v1<_Tp>, _Lp>(*this, std::nothrow); }
00671 
00672       using _Base_type::use_count;
00673       using _Base_type::expired;
00674       using _Base_type::reset;
00675 
00676     private:
00677       // Used by __enable_shared_from_this.
00678       void
00679       _M_assign(element_type* __ptr,
00680                 const __shared_count<_Lp>& __refcount) noexcept
00681       { this->_Base_type::_M_assign(__ptr, __refcount); }
00682 
00683       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
00684       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
00685       friend class __enable_shared_from_this<_Tp, _Lp>;
00686       friend class experimental::enable_shared_from_this<_Tp>;
00687       friend class enable_shared_from_this<_Tp>;
00688     };
00689 
00690 _GLIBCXX_END_NAMESPACE_VERSION
00691 
00692 namespace experimental
00693 {
00694 inline namespace fundamentals_v2
00695 {
00696 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00697 
00698     // 8.2.1
00699 
00700   template<typename _Tp> class shared_ptr;
00701   template<typename _Tp> class weak_ptr;
00702 
00703   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
00704     using __shared_ptr = std::__shared_ptr<__libfund_v1<_Tp>, _Lp>;
00705 
00706   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
00707     using __weak_ptr = std::__weak_ptr<__libfund_v1<_Tp>, _Lp>;
00708 
00709   template<typename _Tp>
00710     class shared_ptr : public __shared_ptr<_Tp>
00711     {
00712       using _Base_type = __shared_ptr<_Tp>;
00713 
00714     public:
00715       using element_type = typename _Base_type::element_type;
00716 
00717     private:
00718       // Constraint for construction from a pointer of type _Yp*:
00719       template<typename _Yp>
00720         using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
00721 
00722       template<typename _Tp1, typename _Res = void>
00723         using _Compatible
00724           = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
00725 
00726       template<typename _Tp1, typename _Del,
00727                typename _Ptr = typename unique_ptr<_Tp1, _Del>::pointer,
00728                typename _Res = void>
00729         using _UniqCompatible = enable_if_t<
00730           __sp_compatible_v<_Tp1, _Tp>
00731           && experimental::is_convertible_v<_Ptr, element_type*>,
00732           _Res>;
00733 
00734     public:
00735 
00736       // 8.2.1.1, shared_ptr constructors
00737       constexpr shared_ptr() noexcept = default;
00738 
00739       template<typename _Tp1, typename = _SafeConv<_Tp1>>
00740         explicit
00741         shared_ptr(_Tp1* __p) : _Base_type(__p)
00742         { _M_enable_shared_from_this_with(__p); }
00743 
00744       template<typename _Tp1, typename _Deleter, typename = _SafeConv<_Tp1>>
00745         shared_ptr(_Tp1* __p, _Deleter __d)
00746         : _Base_type(__p, __d)
00747         { _M_enable_shared_from_this_with(__p); }
00748 
00749       template<typename _Tp1, typename _Deleter, typename _Alloc,
00750                typename = _SafeConv<_Tp1>>
00751         shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
00752         : _Base_type(__p, __d, __a)
00753         { _M_enable_shared_from_this_with(__p); }
00754 
00755       template<typename _Deleter>
00756         shared_ptr(nullptr_t __p, _Deleter __d)
00757         : _Base_type(__p, __d) { }
00758 
00759       template<typename _Deleter, typename _Alloc>
00760         shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
00761         : _Base_type(__p, __d, __a) { }
00762 
00763       template<typename _Tp1>
00764         shared_ptr(const shared_ptr<_Tp1>& __r, element_type* __p) noexcept
00765         : _Base_type(__r, __p) { }
00766 
00767       shared_ptr(const shared_ptr& __r) noexcept
00768         : _Base_type(__r) { }
00769 
00770       template<typename _Tp1, typename = _Compatible<_Tp1>>
00771         shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
00772         : _Base_type(__r) { }
00773 
00774       shared_ptr(shared_ptr&& __r) noexcept
00775       : _Base_type(std::move(__r)) { }
00776 
00777       template<typename _Tp1, typename = _Compatible<_Tp1>>
00778         shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
00779         : _Base_type(std::move(__r)) { }
00780 
00781       template<typename _Tp1, typename = _Compatible<_Tp1>>
00782         explicit
00783         shared_ptr(const weak_ptr<_Tp1>& __r)
00784         : _Base_type(__r) { }
00785 
00786 #if _GLIBCXX_USE_DEPRECATED
00787       template<typename _Tp1, typename = _Compatible<_Tp1>>
00788         shared_ptr(std::auto_ptr<_Tp1>&& __r)
00789         : _Base_type(std::move(__r))
00790         { _M_enable_shared_from_this_with(static_cast<_Tp1*>(this->get())); }
00791 #endif
00792 
00793       template<typename _Tp1, typename _Del,
00794                typename = _UniqCompatible<_Tp1, _Del>>
00795         shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
00796         : _Base_type(std::move(__r))
00797         {
00798           // XXX assume conversion from __r.get() to this->get() to __elem_t*
00799           // is a round trip, which might not be true in all cases.
00800           using __elem_t = typename unique_ptr<_Tp1, _Del>::element_type;
00801           _M_enable_shared_from_this_with(static_cast<__elem_t*>(this->get()));
00802         }
00803 
00804       constexpr shared_ptr(nullptr_t __p)
00805       : _Base_type(__p) { }
00806 
00807       // C++14 §20.8.2.2
00808       ~shared_ptr() = default;
00809 
00810       // C++14 §20.8.2.3
00811       shared_ptr& operator=(const shared_ptr&) noexcept = default;
00812 
00813       template <typename _Tp1>
00814         _Compatible<_Tp1, shared_ptr&>
00815         operator=(const shared_ptr<_Tp1>& __r) noexcept
00816         {
00817           _Base_type::operator=(__r);
00818           return *this;
00819         }
00820 
00821       shared_ptr&
00822       operator=(shared_ptr&& __r) noexcept
00823       {
00824         _Base_type::operator=(std::move(__r));
00825         return *this;
00826       }
00827 
00828       template <typename _Tp1>
00829         _Compatible<_Tp1, shared_ptr&>
00830         operator=(shared_ptr<_Tp1>&& __r) noexcept
00831         {
00832           _Base_type::operator=(std::move(__r));
00833           return *this;
00834         }
00835 
00836 #if _GLIBCXX_USE_DEPRECATED
00837       template<typename _Tp1>
00838         _Compatible<_Tp1, shared_ptr&>
00839         operator=(std::auto_ptr<_Tp1>&& __r)
00840         {
00841           __shared_ptr<_Tp>::operator=(std::move(__r));
00842           return *this;
00843         }
00844 #endif
00845 
00846       template <typename _Tp1, typename _Del>
00847         _UniqCompatible<_Tp1, _Del, shared_ptr&>
00848         operator=(unique_ptr<_Tp1, _Del>&& __r)
00849         {
00850           _Base_type::operator=(std::move(__r));
00851           return *this;
00852         }
00853 
00854       // C++14 §20.8.2.2.4
00855       // swap & reset
00856       // 8.2.1.2 shared_ptr observers
00857       // in __shared_ptr
00858 
00859     private:
00860       template<typename _Alloc, typename... _Args>
00861         shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
00862                    _Args&&... __args)
00863         : _Base_type(__tag, __a, std::forward<_Args>(__args)...)
00864         { _M_enable_shared_from_this_with(this->get()); }
00865 
00866       template<typename _Tp1, typename _Alloc, typename... _Args>
00867         friend shared_ptr<_Tp1>
00868         allocate_shared(const _Alloc& __a, _Args&&...  __args);
00869 
00870       shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
00871       : _Base_type(__r, std::nothrow) { }
00872 
00873       friend class weak_ptr<_Tp>;
00874 
00875       template<typename _Yp>
00876         using __esft_base_t =
00877           decltype(__expt_enable_shared_from_this_base(std::declval<_Yp*>()));
00878 
00879       // Detect an accessible and unambiguous enable_shared_from_this base.
00880       template<typename _Yp, typename = void>
00881         struct __has_esft_base
00882         : false_type { };
00883 
00884       template<typename _Yp>
00885         struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
00886         : __bool_constant<!is_array_v<_Tp>> { };  // ignore base for arrays
00887 
00888       template<typename _Yp>
00889         typename enable_if<__has_esft_base<_Yp>::value>::type
00890         _M_enable_shared_from_this_with(const _Yp* __p) noexcept
00891         {
00892           if (auto __base = __expt_enable_shared_from_this_base(__p))
00893             {
00894               __base->_M_weak_this
00895                 = shared_ptr<_Yp>(*this, const_cast<_Yp*>(__p));
00896             }
00897         }
00898 
00899       template<typename _Yp>
00900         typename enable_if<!__has_esft_base<_Yp>::value>::type
00901         _M_enable_shared_from_this_with(const _Yp*) noexcept
00902         { }
00903     };
00904 
00905   // C++14 §20.8.2.2.7 //DOING
00906   template<typename _Tp1, typename _Tp2>
00907     bool operator==(const shared_ptr<_Tp1>& __a,
00908                     const shared_ptr<_Tp2>& __b) noexcept
00909     { return __a.get() == __b.get(); }
00910 
00911   template<typename _Tp>
00912     inline bool
00913     operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00914     { return !__a; }
00915 
00916   template<typename _Tp>
00917     inline bool
00918     operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00919     { return !__a; }
00920 
00921   template<typename _Tp1, typename _Tp2>
00922     inline bool
00923     operator!=(const shared_ptr<_Tp1>& __a,
00924                const shared_ptr<_Tp2>& __b) noexcept
00925     { return __a.get() != __b.get(); }
00926 
00927   template<typename _Tp>
00928     inline bool
00929     operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00930     { return (bool)__a; }
00931 
00932   template<typename _Tp>
00933     inline bool
00934     operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00935     { return (bool)__a; }
00936 
00937   template<typename _Tp1, typename _Tp2>
00938     inline bool
00939     operator<(const shared_ptr<_Tp1>& __a,
00940               const shared_ptr<_Tp2>& __b) noexcept
00941     {
00942       using __elem_t1 = typename shared_ptr<_Tp1>::element_type;
00943       using __elem_t2 = typename shared_ptr<_Tp2>::element_type;
00944       using _CT = common_type_t<__elem_t1*, __elem_t2*>;
00945       return std::less<_CT>()(__a.get(), __b.get());
00946     }
00947 
00948   template<typename _Tp>
00949     inline bool
00950     operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00951     {
00952       using __elem_t = typename shared_ptr<_Tp>::element_type;
00953       return std::less<__elem_t*>()(__a.get(), nullptr);
00954     }
00955 
00956   template<typename _Tp>
00957     inline bool
00958     operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00959     {
00960       using __elem_t = typename shared_ptr<_Tp>::element_type;
00961       return std::less<__elem_t*>()(nullptr, __a.get());
00962     }
00963 
00964   template<typename _Tp1, typename _Tp2>
00965     inline bool
00966     operator<=(const shared_ptr<_Tp1>& __a,
00967                const shared_ptr<_Tp2>& __b) noexcept
00968     { return !(__b < __a); }
00969 
00970   template<typename _Tp>
00971     inline bool
00972     operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00973     { return !(nullptr < __a); }
00974 
00975   template<typename _Tp>
00976     inline bool
00977     operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00978     { return !(__a < nullptr); }
00979 
00980   template<typename _Tp1, typename _Tp2>
00981     inline bool
00982     operator>(const shared_ptr<_Tp1>& __a,
00983               const shared_ptr<_Tp2>& __b) noexcept
00984     { return (__b < __a); }
00985 
00986   template<typename _Tp>
00987     inline bool
00988     operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
00989     {
00990       using __elem_t = typename shared_ptr<_Tp>::element_type;
00991       return std::less<__elem_t*>()(nullptr, __a.get());
00992     }
00993 
00994   template<typename _Tp>
00995     inline bool
00996     operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
00997     {
00998       using __elem_t = typename shared_ptr<_Tp>::element_type;
00999       return std::less<__elem_t*>()(__a.get(), nullptr);
01000     }
01001 
01002   template<typename _Tp1, typename _Tp2>
01003     inline bool
01004     operator>=(const shared_ptr<_Tp1>& __a,
01005                const shared_ptr<_Tp2>& __b) noexcept
01006     { return !(__a < __b); }
01007 
01008   template<typename _Tp>
01009     inline bool
01010     operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
01011     { return !(__a < nullptr); }
01012 
01013   template<typename _Tp>
01014     inline bool
01015     operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
01016     { return !(nullptr < __a); }
01017 
01018   // C++14 §20.8.2.2.8
01019   template<typename _Tp>
01020     inline void
01021     swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
01022     { __a.swap(__b); }
01023 
01024   // 8.2.1.3, shared_ptr casts
01025   template<typename _Tp, typename _Tp1>
01026     inline shared_ptr<_Tp>
01027     static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
01028     {
01029       using __elem_t = typename shared_ptr<_Tp>::element_type;
01030       return shared_ptr<_Tp>(__r, static_cast<__elem_t*>(__r.get()));
01031     }
01032 
01033   template<typename _Tp, typename _Tp1>
01034     inline shared_ptr<_Tp>
01035     dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
01036     {
01037       using __elem_t = typename shared_ptr<_Tp>::element_type;
01038       if (_Tp* __p = dynamic_cast<__elem_t*>(__r.get()))
01039         return shared_ptr<_Tp>(__r, __p);
01040       return shared_ptr<_Tp>();
01041     }
01042 
01043   template<typename _Tp, typename _Tp1>
01044     inline shared_ptr<_Tp>
01045     const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
01046     {
01047       using __elem_t = typename shared_ptr<_Tp>::element_type;
01048       return shared_ptr<_Tp>(__r, const_cast<__elem_t*>(__r.get()));
01049     }
01050 
01051   template<typename _Tp, typename _Tp1>
01052     inline shared_ptr<_Tp>
01053     reinterpret_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
01054     {
01055       using __elem_t = typename shared_ptr<_Tp>::element_type;
01056       return shared_ptr<_Tp>(__r, reinterpret_cast<__elem_t*>(__r.get()));
01057     }
01058 
01059   // C++14 §20.8.2.3
01060   template<typename _Tp>
01061     class weak_ptr : public __weak_ptr<_Tp>
01062     {
01063       template<typename _Tp1, typename _Res = void>
01064         using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
01065 
01066       using _Base_type = __weak_ptr<_Tp>;
01067 
01068      public:
01069        constexpr weak_ptr() noexcept = default;
01070 
01071        template<typename _Tp1, typename = _Compatible<_Tp1>>
01072          weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
01073          : _Base_type(__r) { }
01074 
01075        weak_ptr(const weak_ptr&) noexcept = default;
01076 
01077        template<typename _Tp1, typename = _Compatible<_Tp1>>
01078          weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
01079          : _Base_type(__r) { }
01080 
01081        weak_ptr(weak_ptr&&) noexcept = default;
01082 
01083        template<typename _Tp1, typename = _Compatible<_Tp1>>
01084          weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
01085          : _Base_type(std::move(__r)) { }
01086 
01087        weak_ptr&
01088        operator=(const weak_ptr& __r) noexcept = default;
01089 
01090        template<typename _Tp1>
01091          _Compatible<_Tp1, weak_ptr&>
01092          operator=(const weak_ptr<_Tp1>& __r) noexcept
01093          {
01094            this->_Base_type::operator=(__r);
01095            return *this;
01096          }
01097 
01098        template<typename _Tp1>
01099          _Compatible<_Tp1, weak_ptr&>
01100          operator=(const shared_ptr<_Tp1>& __r) noexcept
01101          {
01102            this->_Base_type::operator=(__r);
01103            return *this;
01104          }
01105 
01106        weak_ptr&
01107        operator=(weak_ptr&& __r) noexcept = default;
01108 
01109        template<typename _Tp1>
01110          _Compatible<_Tp1, weak_ptr&>
01111          operator=(weak_ptr<_Tp1>&& __r) noexcept
01112          {
01113            this->_Base_type::operator=(std::move(__r));
01114            return *this;
01115          }
01116 
01117        shared_ptr<_Tp>
01118        lock() const noexcept
01119        { return shared_ptr<_Tp>(*this, std::nothrow); }
01120 
01121        friend class enable_shared_from_this<_Tp>;
01122     };
01123 
01124   // C++14 §20.8.2.3.6
01125   template<typename _Tp>
01126     inline void
01127     swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
01128     { __a.swap(__b); }
01129 
01130   /// C++14 §20.8.2.2.10
01131   template<typename _Del, typename _Tp, _Lock_policy _Lp>
01132     inline _Del*
01133     get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
01134     { return std::get_deleter<_Del>(__p); }
01135 
01136   // C++14 §20.8.2.2.11
01137   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
01138     inline std::basic_ostream<_Ch, _Tr>&
01139     operator<<(std::basic_ostream<_Ch, _Tr>& __os,
01140                const __shared_ptr<_Tp, _Lp>& __p)
01141     {
01142       __os << __p.get();
01143       return __os;
01144     }
01145 
01146   // C++14 §20.8.2.4
01147   template<typename _Tp = void> class owner_less;
01148 
01149    /// Partial specialization of owner_less for shared_ptr.
01150   template<typename _Tp>
01151     struct owner_less<shared_ptr<_Tp>>
01152     : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
01153     { };
01154 
01155   /// Partial specialization of owner_less for weak_ptr.
01156   template<typename _Tp>
01157     struct owner_less<weak_ptr<_Tp>>
01158     : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
01159     { };
01160 
01161   template<>
01162     class owner_less<void>
01163     {
01164       template<typename _Tp, typename _Up>
01165         bool
01166         operator()(shared_ptr<_Tp> const& __lhs,
01167                    shared_ptr<_Up> const& __rhs) const
01168         { return __lhs.owner_before(__rhs); }
01169 
01170       template<typename _Tp, typename _Up>
01171         bool
01172         operator()(shared_ptr<_Tp> const& __lhs,
01173                    weak_ptr<_Up> const& __rhs) const
01174         { return __lhs.owner_before(__rhs); }
01175 
01176       template<typename _Tp, typename _Up>
01177         bool
01178         operator()(weak_ptr<_Tp> const& __lhs,
01179                    shared_ptr<_Up> const& __rhs) const
01180         { return __lhs.owner_before(__rhs); }
01181 
01182       template<typename _Tp, typename _Up>
01183         bool
01184         operator()(weak_ptr<_Tp> const& __lhs,
01185                    weak_ptr<_Up> const& __rhs) const
01186         { return __lhs.owner_before(__rhs); }
01187 
01188       typedef void is_transparent;
01189     };
01190 
01191    // C++14 §20.8.2.6
01192    template<typename _Tp>
01193      inline bool
01194      atomic_is_lock_free(const shared_ptr<_Tp>* __p)
01195      { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }
01196 
01197    template<typename _Tp>
01198      shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p)
01199      { return std::atomic_load<_Tp>(__p); }
01200 
01201    template<typename _Tp>
01202      shared_ptr<_Tp>
01203      atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order __mo)
01204      { return std::atomic_load_explicit<_Tp>(__p, __mo); }
01205 
01206    template<typename _Tp>
01207      void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
01208      { return std::atomic_store<_Tp>(__p, __r); }
01209 
01210    template<typename _Tp>
01211      shared_ptr<_Tp>
01212      atomic_store_explicit(const shared_ptr<_Tp>* __p,
01213                            shared_ptr<_Tp> __r,
01214                            memory_order __mo)
01215      { return std::atomic_store_explicit<_Tp>(__p, __r, __mo); }
01216 
01217    template<typename _Tp>
01218      void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
01219      { return std::atomic_exchange<_Tp>(__p, __r); }
01220 
01221    template<typename _Tp>
01222      shared_ptr<_Tp>
01223      atomic_exchange_explicit(const shared_ptr<_Tp>* __p,
01224                               shared_ptr<_Tp> __r,
01225                               memory_order __mo)
01226      { return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); }
01227 
01228    template<typename _Tp>
01229      bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p,
01230                                        shared_ptr<_Tp>* __v,
01231                                        shared_ptr<_Tp> __w)
01232      { return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); }
01233 
01234    template<typename _Tp>
01235      bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p,
01236                                          shared_ptr<_Tp>* __v,
01237                                          shared_ptr<_Tp> __w)
01238      { return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); }
01239 
01240    template<typename _Tp>
01241      bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
01242                                                 shared_ptr<_Tp>* __v,
01243                                                 shared_ptr<_Tp> __w,
01244                                                 memory_order __success,
01245                                                 memory_order __failure)
01246      { return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w,
01247                                                               __success,
01248                                                               __failure); }
01249 
01250    template<typename _Tp>
01251      bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
01252                                                   shared_ptr<_Tp>* __v,
01253                                                   shared_ptr<_Tp> __w,
01254                                                   memory_order __success,
01255                                                   memory_order __failure)
01256      { return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w,
01257                                                                 __success,
01258                                                                 __failure); }
01259 
01260   //enable_shared_from_this
01261   template<typename _Tp>
01262     class enable_shared_from_this
01263     {
01264     protected:
01265       constexpr enable_shared_from_this() noexcept { }
01266 
01267       enable_shared_from_this(const enable_shared_from_this&) noexcept { }
01268 
01269       enable_shared_from_this&
01270       operator=(const enable_shared_from_this&) noexcept
01271       { return *this; }
01272 
01273       ~enable_shared_from_this() { }
01274 
01275     public:
01276       shared_ptr<_Tp>
01277       shared_from_this()
01278       { return shared_ptr<_Tp>(this->_M_weak_this); }
01279 
01280       shared_ptr<const _Tp>
01281       shared_from_this() const
01282       { return shared_ptr<const _Tp>(this->_M_weak_this); }
01283 
01284       weak_ptr<_Tp>
01285       weak_from_this() noexcept
01286       { return _M_weak_this; }
01287 
01288       weak_ptr<const _Tp>
01289       weak_from_this() const noexcept
01290       { return _M_weak_this; }
01291 
01292     private:
01293       template<typename _Tp1>
01294         void
01295         _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
01296         { _M_weak_this._M_assign(__p, __n); }
01297 
01298       // Found by ADL when this is an associated class.
01299       friend const enable_shared_from_this*
01300       __expt_enable_shared_from_this_base(const enable_shared_from_this* __p)
01301       { return __p; }
01302 
01303       template<typename>
01304         friend class shared_ptr;
01305 
01306       mutable weak_ptr<_Tp> _M_weak_this;
01307     };
01308 
01309 _GLIBCXX_END_NAMESPACE_VERSION
01310 } // namespace fundamentals_v2
01311 } // namespace experimental
01312 
01313 _GLIBCXX_BEGIN_NAMESPACE_VERSION
01314 
01315   /// std::hash specialization for shared_ptr.
01316   template<typename _Tp>
01317     struct hash<experimental::shared_ptr<_Tp>>
01318     : public __hash_base<size_t, experimental::shared_ptr<_Tp>>
01319     {
01320       size_t
01321       operator()(const experimental::shared_ptr<_Tp>& __s) const noexcept
01322       { return std::hash<_Tp*>()(__s.get()); }
01323     };
01324 
01325 _GLIBCXX_END_NAMESPACE_VERSION
01326 } // namespace std
01327 
01328 #endif // __cplusplus <= 201103L
01329 
01330 #endif // _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H