libstdc++
|
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