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 // 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