libstdc++
|
00001 // shared_ptr and weak_ptr implementation -*- C++ -*- 00002 00003 // Copyright (C) 2007-2018 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 // GCC Note: Based on files from version 1.32.0 of the Boost library. 00026 00027 // shared_count.hpp 00028 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 00029 00030 // shared_ptr.hpp 00031 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. 00032 // Copyright (C) 2001, 2002, 2003 Peter Dimov 00033 00034 // weak_ptr.hpp 00035 // Copyright (C) 2001, 2002, 2003 Peter Dimov 00036 00037 // enable_shared_from_this.hpp 00038 // Copyright (C) 2002 Peter Dimov 00039 00040 // Distributed under the Boost Software License, Version 1.0. (See 00041 // accompanying file LICENSE_1_0.txt or copy at 00042 // http://www.boost.org/LICENSE_1_0.txt) 00043 00044 /** @file 00045 * This is an internal header file, included by other library headers. 00046 * Do not attempt to use it directly. @headername{memory} 00047 */ 00048 00049 #ifndef _SHARED_PTR_H 00050 #define _SHARED_PTR_H 1 00051 00052 #include <bits/shared_ptr_base.h> 00053 00054 namespace std _GLIBCXX_VISIBILITY(default) 00055 { 00056 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00057 00058 /** 00059 * @addtogroup pointer_abstractions 00060 * @{ 00061 */ 00062 00063 /// 20.7.2.2.11 shared_ptr I/O 00064 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> 00065 inline std::basic_ostream<_Ch, _Tr>& 00066 operator<<(std::basic_ostream<_Ch, _Tr>& __os, 00067 const __shared_ptr<_Tp, _Lp>& __p) 00068 { 00069 __os << __p.get(); 00070 return __os; 00071 } 00072 00073 template<typename _Del, typename _Tp, _Lock_policy _Lp> 00074 inline _Del* 00075 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept 00076 { 00077 #if __cpp_rtti 00078 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 00079 #else 00080 return 0; 00081 #endif 00082 } 00083 00084 /// 20.7.2.2.10 shared_ptr get_deleter 00085 template<typename _Del, typename _Tp> 00086 inline _Del* 00087 get_deleter(const shared_ptr<_Tp>& __p) noexcept 00088 { 00089 #if __cpp_rtti 00090 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 00091 #else 00092 return 0; 00093 #endif 00094 } 00095 00096 /** 00097 * @brief A smart pointer with reference-counted copy semantics. 00098 * 00099 * The object pointed to is deleted when the last shared_ptr pointing to 00100 * it is destroyed or reset. 00101 */ 00102 template<typename _Tp> 00103 class shared_ptr : public __shared_ptr<_Tp> 00104 { 00105 template<typename... _Args> 00106 using _Constructible = typename enable_if< 00107 is_constructible<__shared_ptr<_Tp>, _Args...>::value 00108 >::type; 00109 00110 template<typename _Arg> 00111 using _Assignable = typename enable_if< 00112 is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr& 00113 >::type; 00114 00115 public: 00116 00117 using element_type = typename __shared_ptr<_Tp>::element_type; 00118 00119 #if __cplusplus > 201402L 00120 # define __cpp_lib_shared_ptr_weak_type 201606 00121 using weak_type = weak_ptr<_Tp>; 00122 #endif 00123 /** 00124 * @brief Construct an empty %shared_ptr. 00125 * @post use_count()==0 && get()==0 00126 */ 00127 constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { } 00128 00129 shared_ptr(const shared_ptr&) noexcept = default; 00130 00131 /** 00132 * @brief Construct a %shared_ptr that owns the pointer @a __p. 00133 * @param __p A pointer that is convertible to element_type*. 00134 * @post use_count() == 1 && get() == __p 00135 * @throw std::bad_alloc, in which case @c delete @a __p is called. 00136 */ 00137 template<typename _Yp, typename = _Constructible<_Yp*>> 00138 explicit 00139 shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { } 00140 00141 /** 00142 * @brief Construct a %shared_ptr that owns the pointer @a __p 00143 * and the deleter @a __d. 00144 * @param __p A pointer. 00145 * @param __d A deleter. 00146 * @post use_count() == 1 && get() == __p 00147 * @throw std::bad_alloc, in which case @a __d(__p) is called. 00148 * 00149 * Requirements: _Deleter's copy constructor and destructor must 00150 * not throw 00151 * 00152 * __shared_ptr will release __p by calling __d(__p) 00153 */ 00154 template<typename _Yp, typename _Deleter, 00155 typename = _Constructible<_Yp*, _Deleter>> 00156 shared_ptr(_Yp* __p, _Deleter __d) 00157 : __shared_ptr<_Tp>(__p, std::move(__d)) { } 00158 00159 /** 00160 * @brief Construct a %shared_ptr that owns a null pointer 00161 * and the deleter @a __d. 00162 * @param __p A null pointer constant. 00163 * @param __d A deleter. 00164 * @post use_count() == 1 && get() == __p 00165 * @throw std::bad_alloc, in which case @a __d(__p) is called. 00166 * 00167 * Requirements: _Deleter's copy constructor and destructor must 00168 * not throw 00169 * 00170 * The last owner will call __d(__p) 00171 */ 00172 template<typename _Deleter> 00173 shared_ptr(nullptr_t __p, _Deleter __d) 00174 : __shared_ptr<_Tp>(__p, std::move(__d)) { } 00175 00176 /** 00177 * @brief Construct a %shared_ptr that owns the pointer @a __p 00178 * and the deleter @a __d. 00179 * @param __p A pointer. 00180 * @param __d A deleter. 00181 * @param __a An allocator. 00182 * @post use_count() == 1 && get() == __p 00183 * @throw std::bad_alloc, in which case @a __d(__p) is called. 00184 * 00185 * Requirements: _Deleter's copy constructor and destructor must 00186 * not throw _Alloc's copy constructor and destructor must not 00187 * throw. 00188 * 00189 * __shared_ptr will release __p by calling __d(__p) 00190 */ 00191 template<typename _Yp, typename _Deleter, typename _Alloc, 00192 typename = _Constructible<_Yp*, _Deleter, _Alloc>> 00193 shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a) 00194 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } 00195 00196 /** 00197 * @brief Construct a %shared_ptr that owns a null pointer 00198 * and the deleter @a __d. 00199 * @param __p A null pointer constant. 00200 * @param __d A deleter. 00201 * @param __a An allocator. 00202 * @post use_count() == 1 && get() == __p 00203 * @throw std::bad_alloc, in which case @a __d(__p) is called. 00204 * 00205 * Requirements: _Deleter's copy constructor and destructor must 00206 * not throw _Alloc's copy constructor and destructor must not 00207 * throw. 00208 * 00209 * The last owner will call __d(__p) 00210 */ 00211 template<typename _Deleter, typename _Alloc> 00212 shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 00213 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } 00214 00215 // Aliasing constructor 00216 00217 /** 00218 * @brief Constructs a %shared_ptr instance that stores @a __p 00219 * and shares ownership with @a __r. 00220 * @param __r A %shared_ptr. 00221 * @param __p A pointer that will remain valid while @a *__r is valid. 00222 * @post get() == __p && use_count() == __r.use_count() 00223 * 00224 * This can be used to construct a @c shared_ptr to a sub-object 00225 * of an object managed by an existing @c shared_ptr. 00226 * 00227 * @code 00228 * shared_ptr< pair<int,int> > pii(new pair<int,int>()); 00229 * shared_ptr<int> pi(pii, &pii->first); 00230 * assert(pii.use_count() == 2); 00231 * @endcode 00232 */ 00233 template<typename _Yp> 00234 shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept 00235 : __shared_ptr<_Tp>(__r, __p) { } 00236 00237 /** 00238 * @brief If @a __r is empty, constructs an empty %shared_ptr; 00239 * otherwise construct a %shared_ptr that shares ownership 00240 * with @a __r. 00241 * @param __r A %shared_ptr. 00242 * @post get() == __r.get() && use_count() == __r.use_count() 00243 */ 00244 template<typename _Yp, 00245 typename = _Constructible<const shared_ptr<_Yp>&>> 00246 shared_ptr(const shared_ptr<_Yp>& __r) noexcept 00247 : __shared_ptr<_Tp>(__r) { } 00248 00249 /** 00250 * @brief Move-constructs a %shared_ptr instance from @a __r. 00251 * @param __r A %shared_ptr rvalue. 00252 * @post *this contains the old value of @a __r, @a __r is empty. 00253 */ 00254 shared_ptr(shared_ptr&& __r) noexcept 00255 : __shared_ptr<_Tp>(std::move(__r)) { } 00256 00257 /** 00258 * @brief Move-constructs a %shared_ptr instance from @a __r. 00259 * @param __r A %shared_ptr rvalue. 00260 * @post *this contains the old value of @a __r, @a __r is empty. 00261 */ 00262 template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>> 00263 shared_ptr(shared_ptr<_Yp>&& __r) noexcept 00264 : __shared_ptr<_Tp>(std::move(__r)) { } 00265 00266 /** 00267 * @brief Constructs a %shared_ptr that shares ownership with @a __r 00268 * and stores a copy of the pointer stored in @a __r. 00269 * @param __r A weak_ptr. 00270 * @post use_count() == __r.use_count() 00271 * @throw bad_weak_ptr when __r.expired(), 00272 * in which case the constructor has no effect. 00273 */ 00274 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> 00275 explicit shared_ptr(const weak_ptr<_Yp>& __r) 00276 : __shared_ptr<_Tp>(__r) { } 00277 00278 #if _GLIBCXX_USE_DEPRECATED 00279 #pragma GCC diagnostic push 00280 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00281 template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>> 00282 shared_ptr(auto_ptr<_Yp>&& __r); 00283 #pragma GCC diagnostic pop 00284 #endif 00285 00286 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00287 // 2399. shared_ptr's constructor from unique_ptr should be constrained 00288 template<typename _Yp, typename _Del, 00289 typename = _Constructible<unique_ptr<_Yp, _Del>>> 00290 shared_ptr(unique_ptr<_Yp, _Del>&& __r) 00291 : __shared_ptr<_Tp>(std::move(__r)) { } 00292 00293 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED 00294 // This non-standard constructor exists to support conversions that 00295 // were possible in C++11 and C++14 but are ill-formed in C++17. 00296 // If an exception is thrown this constructor has no effect. 00297 template<typename _Yp, typename _Del, 00298 _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0> 00299 shared_ptr(unique_ptr<_Yp, _Del>&& __r) 00300 : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { } 00301 #endif 00302 00303 /** 00304 * @brief Construct an empty %shared_ptr. 00305 * @post use_count() == 0 && get() == nullptr 00306 */ 00307 constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { } 00308 00309 shared_ptr& operator=(const shared_ptr&) noexcept = default; 00310 00311 template<typename _Yp> 00312 _Assignable<const shared_ptr<_Yp>&> 00313 operator=(const shared_ptr<_Yp>& __r) noexcept 00314 { 00315 this->__shared_ptr<_Tp>::operator=(__r); 00316 return *this; 00317 } 00318 00319 #if _GLIBCXX_USE_DEPRECATED 00320 #pragma GCC diagnostic push 00321 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00322 template<typename _Yp> 00323 _Assignable<auto_ptr<_Yp>> 00324 operator=(auto_ptr<_Yp>&& __r) 00325 { 00326 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 00327 return *this; 00328 } 00329 #pragma GCC diagnostic pop 00330 #endif 00331 00332 shared_ptr& 00333 operator=(shared_ptr&& __r) noexcept 00334 { 00335 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 00336 return *this; 00337 } 00338 00339 template<class _Yp> 00340 _Assignable<shared_ptr<_Yp>> 00341 operator=(shared_ptr<_Yp>&& __r) noexcept 00342 { 00343 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 00344 return *this; 00345 } 00346 00347 template<typename _Yp, typename _Del> 00348 _Assignable<unique_ptr<_Yp, _Del>> 00349 operator=(unique_ptr<_Yp, _Del>&& __r) 00350 { 00351 this->__shared_ptr<_Tp>::operator=(std::move(__r)); 00352 return *this; 00353 } 00354 00355 private: 00356 // This constructor is non-standard, it is used by allocate_shared. 00357 template<typename _Alloc, typename... _Args> 00358 shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) 00359 : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...) 00360 { } 00361 00362 template<typename _Yp, typename _Alloc, typename... _Args> 00363 friend shared_ptr<_Yp> 00364 allocate_shared(const _Alloc& __a, _Args&&... __args); 00365 00366 // This constructor is non-standard, it is used by weak_ptr::lock(). 00367 shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) 00368 : __shared_ptr<_Tp>(__r, std::nothrow) { } 00369 00370 friend class weak_ptr<_Tp>; 00371 }; 00372 00373 #if __cpp_deduction_guides >= 201606 00374 template<typename _Tp> 00375 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; 00376 template<typename _Tp, typename _Del> 00377 shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>; 00378 #endif 00379 00380 // 20.7.2.2.7 shared_ptr comparisons 00381 template<typename _Tp, typename _Up> 00382 inline bool 00383 operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00384 { return __a.get() == __b.get(); } 00385 00386 template<typename _Tp> 00387 inline bool 00388 operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00389 { return !__a; } 00390 00391 template<typename _Tp> 00392 inline bool 00393 operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00394 { return !__a; } 00395 00396 template<typename _Tp, typename _Up> 00397 inline bool 00398 operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00399 { return __a.get() != __b.get(); } 00400 00401 template<typename _Tp> 00402 inline bool 00403 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00404 { return (bool)__a; } 00405 00406 template<typename _Tp> 00407 inline bool 00408 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00409 { return (bool)__a; } 00410 00411 template<typename _Tp, typename _Up> 00412 inline bool 00413 operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00414 { 00415 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 00416 using _Up_elt = typename shared_ptr<_Up>::element_type; 00417 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; 00418 return less<_Vp>()(__a.get(), __b.get()); 00419 } 00420 00421 template<typename _Tp> 00422 inline bool 00423 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00424 { 00425 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 00426 return less<_Tp_elt*>()(__a.get(), nullptr); 00427 } 00428 00429 template<typename _Tp> 00430 inline bool 00431 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00432 { 00433 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 00434 return less<_Tp_elt*>()(nullptr, __a.get()); 00435 } 00436 00437 template<typename _Tp, typename _Up> 00438 inline bool 00439 operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00440 { return !(__b < __a); } 00441 00442 template<typename _Tp> 00443 inline bool 00444 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00445 { return !(nullptr < __a); } 00446 00447 template<typename _Tp> 00448 inline bool 00449 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00450 { return !(__a < nullptr); } 00451 00452 template<typename _Tp, typename _Up> 00453 inline bool 00454 operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00455 { return (__b < __a); } 00456 00457 template<typename _Tp> 00458 inline bool 00459 operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00460 { return nullptr < __a; } 00461 00462 template<typename _Tp> 00463 inline bool 00464 operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00465 { return __a < nullptr; } 00466 00467 template<typename _Tp, typename _Up> 00468 inline bool 00469 operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00470 { return !(__a < __b); } 00471 00472 template<typename _Tp> 00473 inline bool 00474 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00475 { return !(__a < nullptr); } 00476 00477 template<typename _Tp> 00478 inline bool 00479 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00480 { return !(nullptr < __a); } 00481 00482 template<typename _Tp> 00483 struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> 00484 { }; 00485 00486 // 20.7.2.2.8 shared_ptr specialized algorithms. 00487 template<typename _Tp> 00488 inline void 00489 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept 00490 { __a.swap(__b); } 00491 00492 // 20.7.2.2.9 shared_ptr casts. 00493 template<typename _Tp, typename _Up> 00494 inline shared_ptr<_Tp> 00495 static_pointer_cast(const shared_ptr<_Up>& __r) noexcept 00496 { 00497 using _Sp = shared_ptr<_Tp>; 00498 return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get())); 00499 } 00500 00501 template<typename _Tp, typename _Up> 00502 inline shared_ptr<_Tp> 00503 const_pointer_cast(const shared_ptr<_Up>& __r) noexcept 00504 { 00505 using _Sp = shared_ptr<_Tp>; 00506 return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get())); 00507 } 00508 00509 template<typename _Tp, typename _Up> 00510 inline shared_ptr<_Tp> 00511 dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept 00512 { 00513 using _Sp = shared_ptr<_Tp>; 00514 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get())) 00515 return _Sp(__r, __p); 00516 return _Sp(); 00517 } 00518 00519 #if __cplusplus > 201402L 00520 template<typename _Tp, typename _Up> 00521 inline shared_ptr<_Tp> 00522 reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept 00523 { 00524 using _Sp = shared_ptr<_Tp>; 00525 return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get())); 00526 } 00527 #endif 00528 00529 /** 00530 * @brief A smart pointer with weak semantics. 00531 * 00532 * With forwarding constructors and assignment operators. 00533 */ 00534 template<typename _Tp> 00535 class weak_ptr : public __weak_ptr<_Tp> 00536 { 00537 template<typename _Arg> 00538 using _Constructible = typename enable_if< 00539 is_constructible<__weak_ptr<_Tp>, _Arg>::value 00540 >::type; 00541 00542 template<typename _Arg> 00543 using _Assignable = typename enable_if< 00544 is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr& 00545 >::type; 00546 00547 public: 00548 constexpr weak_ptr() noexcept = default; 00549 00550 template<typename _Yp, 00551 typename = _Constructible<const shared_ptr<_Yp>&>> 00552 weak_ptr(const shared_ptr<_Yp>& __r) noexcept 00553 : __weak_ptr<_Tp>(__r) { } 00554 00555 weak_ptr(const weak_ptr&) noexcept = default; 00556 00557 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> 00558 weak_ptr(const weak_ptr<_Yp>& __r) noexcept 00559 : __weak_ptr<_Tp>(__r) { } 00560 00561 weak_ptr(weak_ptr&&) noexcept = default; 00562 00563 template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>> 00564 weak_ptr(weak_ptr<_Yp>&& __r) noexcept 00565 : __weak_ptr<_Tp>(std::move(__r)) { } 00566 00567 weak_ptr& 00568 operator=(const weak_ptr& __r) noexcept = default; 00569 00570 template<typename _Yp> 00571 _Assignable<const weak_ptr<_Yp>&> 00572 operator=(const weak_ptr<_Yp>& __r) noexcept 00573 { 00574 this->__weak_ptr<_Tp>::operator=(__r); 00575 return *this; 00576 } 00577 00578 template<typename _Yp> 00579 _Assignable<const shared_ptr<_Yp>&> 00580 operator=(const shared_ptr<_Yp>& __r) noexcept 00581 { 00582 this->__weak_ptr<_Tp>::operator=(__r); 00583 return *this; 00584 } 00585 00586 weak_ptr& 00587 operator=(weak_ptr&& __r) noexcept = default; 00588 00589 template<typename _Yp> 00590 _Assignable<weak_ptr<_Yp>> 00591 operator=(weak_ptr<_Yp>&& __r) noexcept 00592 { 00593 this->__weak_ptr<_Tp>::operator=(std::move(__r)); 00594 return *this; 00595 } 00596 00597 shared_ptr<_Tp> 00598 lock() const noexcept 00599 { return shared_ptr<_Tp>(*this, std::nothrow); } 00600 }; 00601 00602 #if __cpp_deduction_guides >= 201606 00603 template<typename _Tp> 00604 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; 00605 #endif 00606 00607 // 20.7.2.3.6 weak_ptr specialized algorithms. 00608 template<typename _Tp> 00609 inline void 00610 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept 00611 { __a.swap(__b); } 00612 00613 00614 /// Primary template owner_less 00615 template<typename _Tp = void> 00616 struct owner_less; 00617 00618 /// Void specialization of owner_less 00619 template<> 00620 struct owner_less<void> : _Sp_owner_less<void, void> 00621 { }; 00622 00623 /// Partial specialization of owner_less for shared_ptr. 00624 template<typename _Tp> 00625 struct owner_less<shared_ptr<_Tp>> 00626 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> 00627 { }; 00628 00629 /// Partial specialization of owner_less for weak_ptr. 00630 template<typename _Tp> 00631 struct owner_less<weak_ptr<_Tp>> 00632 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> 00633 { }; 00634 00635 /** 00636 * @brief Base class allowing use of member function shared_from_this. 00637 */ 00638 template<typename _Tp> 00639 class enable_shared_from_this 00640 { 00641 protected: 00642 constexpr enable_shared_from_this() noexcept { } 00643 00644 enable_shared_from_this(const enable_shared_from_this&) noexcept { } 00645 00646 enable_shared_from_this& 00647 operator=(const enable_shared_from_this&) noexcept 00648 { return *this; } 00649 00650 ~enable_shared_from_this() { } 00651 00652 public: 00653 shared_ptr<_Tp> 00654 shared_from_this() 00655 { return shared_ptr<_Tp>(this->_M_weak_this); } 00656 00657 shared_ptr<const _Tp> 00658 shared_from_this() const 00659 { return shared_ptr<const _Tp>(this->_M_weak_this); } 00660 00661 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 00662 #define __cpp_lib_enable_shared_from_this 201603 00663 weak_ptr<_Tp> 00664 weak_from_this() noexcept 00665 { return this->_M_weak_this; } 00666 00667 weak_ptr<const _Tp> 00668 weak_from_this() const noexcept 00669 { return this->_M_weak_this; } 00670 #endif 00671 00672 private: 00673 template<typename _Tp1> 00674 void 00675 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept 00676 { _M_weak_this._M_assign(__p, __n); } 00677 00678 // Found by ADL when this is an associated class. 00679 friend const enable_shared_from_this* 00680 __enable_shared_from_this_base(const __shared_count<>&, 00681 const enable_shared_from_this* __p) 00682 { return __p; } 00683 00684 template<typename, _Lock_policy> 00685 friend class __shared_ptr; 00686 00687 mutable weak_ptr<_Tp> _M_weak_this; 00688 }; 00689 00690 /** 00691 * @brief Create an object that is owned by a shared_ptr. 00692 * @param __a An allocator. 00693 * @param __args Arguments for the @a _Tp object's constructor. 00694 * @return A shared_ptr that owns the newly created object. 00695 * @throw An exception thrown from @a _Alloc::allocate or from the 00696 * constructor of @a _Tp. 00697 * 00698 * A copy of @a __a will be used to allocate memory for the shared_ptr 00699 * and the new object. 00700 */ 00701 template<typename _Tp, typename _Alloc, typename... _Args> 00702 inline shared_ptr<_Tp> 00703 allocate_shared(const _Alloc& __a, _Args&&... __args) 00704 { 00705 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a}, 00706 std::forward<_Args>(__args)...); 00707 } 00708 00709 /** 00710 * @brief Create an object that is owned by a shared_ptr. 00711 * @param __args Arguments for the @a _Tp object's constructor. 00712 * @return A shared_ptr that owns the newly created object. 00713 * @throw std::bad_alloc, or an exception thrown from the 00714 * constructor of @a _Tp. 00715 */ 00716 template<typename _Tp, typename... _Args> 00717 inline shared_ptr<_Tp> 00718 make_shared(_Args&&... __args) 00719 { 00720 typedef typename std::remove_cv<_Tp>::type _Tp_nc; 00721 return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), 00722 std::forward<_Args>(__args)...); 00723 } 00724 00725 /// std::hash specialization for shared_ptr. 00726 template<typename _Tp> 00727 struct hash<shared_ptr<_Tp>> 00728 : public __hash_base<size_t, shared_ptr<_Tp>> 00729 { 00730 size_t 00731 operator()(const shared_ptr<_Tp>& __s) const noexcept 00732 { 00733 return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get()); 00734 } 00735 }; 00736 00737 // @} group pointer_abstractions 00738 00739 _GLIBCXX_END_NAMESPACE_VERSION 00740 } // namespace 00741 00742 #endif // _SHARED_PTR_H