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_make_shared_tag __tag, const _Alloc& __a, 00359 _Args&&... __args) 00360 : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...) 00361 { } 00362 00363 template<typename _Yp, typename _Alloc, typename... _Args> 00364 friend shared_ptr<_Yp> 00365 allocate_shared(const _Alloc& __a, _Args&&... __args); 00366 00367 // This constructor is non-standard, it is used by weak_ptr::lock(). 00368 shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) 00369 : __shared_ptr<_Tp>(__r, std::nothrow) { } 00370 00371 friend class weak_ptr<_Tp>; 00372 }; 00373 00374 #if __cpp_deduction_guides >= 201606 00375 template<typename _Tp> 00376 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; 00377 template<typename _Tp, typename _Del> 00378 shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>; 00379 #endif 00380 00381 // 20.7.2.2.7 shared_ptr comparisons 00382 template<typename _Tp, typename _Up> 00383 inline bool 00384 operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00385 { return __a.get() == __b.get(); } 00386 00387 template<typename _Tp> 00388 inline bool 00389 operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00390 { return !__a; } 00391 00392 template<typename _Tp> 00393 inline bool 00394 operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00395 { return !__a; } 00396 00397 template<typename _Tp, typename _Up> 00398 inline bool 00399 operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00400 { return __a.get() != __b.get(); } 00401 00402 template<typename _Tp> 00403 inline bool 00404 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00405 { return (bool)__a; } 00406 00407 template<typename _Tp> 00408 inline bool 00409 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00410 { return (bool)__a; } 00411 00412 template<typename _Tp, typename _Up> 00413 inline bool 00414 operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00415 { 00416 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 00417 using _Up_elt = typename shared_ptr<_Up>::element_type; 00418 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; 00419 return less<_Vp>()(__a.get(), __b.get()); 00420 } 00421 00422 template<typename _Tp> 00423 inline bool 00424 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00425 { 00426 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 00427 return less<_Tp_elt*>()(__a.get(), nullptr); 00428 } 00429 00430 template<typename _Tp> 00431 inline bool 00432 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00433 { 00434 using _Tp_elt = typename shared_ptr<_Tp>::element_type; 00435 return less<_Tp_elt*>()(nullptr, __a.get()); 00436 } 00437 00438 template<typename _Tp, typename _Up> 00439 inline bool 00440 operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00441 { return !(__b < __a); } 00442 00443 template<typename _Tp> 00444 inline bool 00445 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00446 { return !(nullptr < __a); } 00447 00448 template<typename _Tp> 00449 inline bool 00450 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00451 { return !(__a < nullptr); } 00452 00453 template<typename _Tp, typename _Up> 00454 inline bool 00455 operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00456 { return (__b < __a); } 00457 00458 template<typename _Tp> 00459 inline bool 00460 operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00461 { return nullptr < __a; } 00462 00463 template<typename _Tp> 00464 inline bool 00465 operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00466 { return __a < nullptr; } 00467 00468 template<typename _Tp, typename _Up> 00469 inline bool 00470 operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 00471 { return !(__a < __b); } 00472 00473 template<typename _Tp> 00474 inline bool 00475 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 00476 { return !(__a < nullptr); } 00477 00478 template<typename _Tp> 00479 inline bool 00480 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 00481 { return !(nullptr < __a); } 00482 00483 template<typename _Tp> 00484 struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> 00485 { }; 00486 00487 // 20.7.2.2.8 shared_ptr specialized algorithms. 00488 template<typename _Tp> 00489 inline void 00490 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept 00491 { __a.swap(__b); } 00492 00493 // 20.7.2.2.9 shared_ptr casts. 00494 template<typename _Tp, typename _Up> 00495 inline shared_ptr<_Tp> 00496 static_pointer_cast(const shared_ptr<_Up>& __r) noexcept 00497 { 00498 using _Sp = shared_ptr<_Tp>; 00499 return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get())); 00500 } 00501 00502 template<typename _Tp, typename _Up> 00503 inline shared_ptr<_Tp> 00504 const_pointer_cast(const shared_ptr<_Up>& __r) noexcept 00505 { 00506 using _Sp = shared_ptr<_Tp>; 00507 return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get())); 00508 } 00509 00510 template<typename _Tp, typename _Up> 00511 inline shared_ptr<_Tp> 00512 dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept 00513 { 00514 using _Sp = shared_ptr<_Tp>; 00515 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get())) 00516 return _Sp(__r, __p); 00517 return _Sp(); 00518 } 00519 00520 #if __cplusplus > 201402L 00521 template<typename _Tp, typename _Up> 00522 inline shared_ptr<_Tp> 00523 reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept 00524 { 00525 using _Sp = shared_ptr<_Tp>; 00526 return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get())); 00527 } 00528 #endif 00529 00530 /** 00531 * @brief A smart pointer with weak semantics. 00532 * 00533 * With forwarding constructors and assignment operators. 00534 */ 00535 template<typename _Tp> 00536 class weak_ptr : public __weak_ptr<_Tp> 00537 { 00538 template<typename _Arg> 00539 using _Constructible = typename enable_if< 00540 is_constructible<__weak_ptr<_Tp>, _Arg>::value 00541 >::type; 00542 00543 template<typename _Arg> 00544 using _Assignable = typename enable_if< 00545 is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr& 00546 >::type; 00547 00548 public: 00549 constexpr weak_ptr() noexcept = default; 00550 00551 template<typename _Yp, 00552 typename = _Constructible<const shared_ptr<_Yp>&>> 00553 weak_ptr(const shared_ptr<_Yp>& __r) noexcept 00554 : __weak_ptr<_Tp>(__r) { } 00555 00556 weak_ptr(const weak_ptr&) noexcept = default; 00557 00558 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> 00559 weak_ptr(const weak_ptr<_Yp>& __r) noexcept 00560 : __weak_ptr<_Tp>(__r) { } 00561 00562 weak_ptr(weak_ptr&&) noexcept = default; 00563 00564 template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>> 00565 weak_ptr(weak_ptr<_Yp>&& __r) noexcept 00566 : __weak_ptr<_Tp>(std::move(__r)) { } 00567 00568 weak_ptr& 00569 operator=(const weak_ptr& __r) noexcept = default; 00570 00571 template<typename _Yp> 00572 _Assignable<const weak_ptr<_Yp>&> 00573 operator=(const weak_ptr<_Yp>& __r) noexcept 00574 { 00575 this->__weak_ptr<_Tp>::operator=(__r); 00576 return *this; 00577 } 00578 00579 template<typename _Yp> 00580 _Assignable<const shared_ptr<_Yp>&> 00581 operator=(const shared_ptr<_Yp>& __r) noexcept 00582 { 00583 this->__weak_ptr<_Tp>::operator=(__r); 00584 return *this; 00585 } 00586 00587 weak_ptr& 00588 operator=(weak_ptr&& __r) noexcept = default; 00589 00590 template<typename _Yp> 00591 _Assignable<weak_ptr<_Yp>> 00592 operator=(weak_ptr<_Yp>&& __r) noexcept 00593 { 00594 this->__weak_ptr<_Tp>::operator=(std::move(__r)); 00595 return *this; 00596 } 00597 00598 shared_ptr<_Tp> 00599 lock() const noexcept 00600 { return shared_ptr<_Tp>(*this, std::nothrow); } 00601 }; 00602 00603 #if __cpp_deduction_guides >= 201606 00604 template<typename _Tp> 00605 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; 00606 #endif 00607 00608 // 20.7.2.3.6 weak_ptr specialized algorithms. 00609 template<typename _Tp> 00610 inline void 00611 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept 00612 { __a.swap(__b); } 00613 00614 00615 /// Primary template owner_less 00616 template<typename _Tp = void> 00617 struct owner_less; 00618 00619 /// Void specialization of owner_less 00620 template<> 00621 struct owner_less<void> : _Sp_owner_less<void, void> 00622 { }; 00623 00624 /// Partial specialization of owner_less for shared_ptr. 00625 template<typename _Tp> 00626 struct owner_less<shared_ptr<_Tp>> 00627 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> 00628 { }; 00629 00630 /// Partial specialization of owner_less for weak_ptr. 00631 template<typename _Tp> 00632 struct owner_less<weak_ptr<_Tp>> 00633 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> 00634 { }; 00635 00636 /** 00637 * @brief Base class allowing use of member function shared_from_this. 00638 */ 00639 template<typename _Tp> 00640 class enable_shared_from_this 00641 { 00642 protected: 00643 constexpr enable_shared_from_this() noexcept { } 00644 00645 enable_shared_from_this(const enable_shared_from_this&) noexcept { } 00646 00647 enable_shared_from_this& 00648 operator=(const enable_shared_from_this&) noexcept 00649 { return *this; } 00650 00651 ~enable_shared_from_this() { } 00652 00653 public: 00654 shared_ptr<_Tp> 00655 shared_from_this() 00656 { return shared_ptr<_Tp>(this->_M_weak_this); } 00657 00658 shared_ptr<const _Tp> 00659 shared_from_this() const 00660 { return shared_ptr<const _Tp>(this->_M_weak_this); } 00661 00662 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 00663 #define __cpp_lib_enable_shared_from_this 201603 00664 weak_ptr<_Tp> 00665 weak_from_this() noexcept 00666 { return this->_M_weak_this; } 00667 00668 weak_ptr<const _Tp> 00669 weak_from_this() const noexcept 00670 { return this->_M_weak_this; } 00671 #endif 00672 00673 private: 00674 template<typename _Tp1> 00675 void 00676 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept 00677 { _M_weak_this._M_assign(__p, __n); } 00678 00679 // Found by ADL when this is an associated class. 00680 friend const enable_shared_from_this* 00681 __enable_shared_from_this_base(const __shared_count<>&, 00682 const enable_shared_from_this* __p) 00683 { return __p; } 00684 00685 template<typename, _Lock_policy> 00686 friend class __shared_ptr; 00687 00688 mutable weak_ptr<_Tp> _M_weak_this; 00689 }; 00690 00691 /** 00692 * @brief Create an object that is owned by a shared_ptr. 00693 * @param __a An allocator. 00694 * @param __args Arguments for the @a _Tp object's constructor. 00695 * @return A shared_ptr that owns the newly created object. 00696 * @throw An exception thrown from @a _Alloc::allocate or from the 00697 * constructor of @a _Tp. 00698 * 00699 * A copy of @a __a will be used to allocate memory for the shared_ptr 00700 * and the new object. 00701 */ 00702 template<typename _Tp, typename _Alloc, typename... _Args> 00703 inline shared_ptr<_Tp> 00704 allocate_shared(const _Alloc& __a, _Args&&... __args) 00705 { 00706 return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a, 00707 std::forward<_Args>(__args)...); 00708 } 00709 00710 /** 00711 * @brief Create an object that is owned by a shared_ptr. 00712 * @param __args Arguments for the @a _Tp object's constructor. 00713 * @return A shared_ptr that owns the newly created object. 00714 * @throw std::bad_alloc, or an exception thrown from the 00715 * constructor of @a _Tp. 00716 */ 00717 template<typename _Tp, typename... _Args> 00718 inline shared_ptr<_Tp> 00719 make_shared(_Args&&... __args) 00720 { 00721 typedef typename std::remove_const<_Tp>::type _Tp_nc; 00722 return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), 00723 std::forward<_Args>(__args)...); 00724 } 00725 00726 /// std::hash specialization for shared_ptr. 00727 template<typename _Tp> 00728 struct hash<shared_ptr<_Tp>> 00729 : public __hash_base<size_t, shared_ptr<_Tp>> 00730 { 00731 size_t 00732 operator()(const shared_ptr<_Tp>& __s) const noexcept 00733 { 00734 return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get()); 00735 } 00736 }; 00737 00738 // @} group pointer_abstractions 00739 00740 _GLIBCXX_END_NAMESPACE_VERSION 00741 } // namespace 00742 00743 #endif // _SHARED_PTR_H