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