libstdc++
|
00001 // shared_ptr and weak_ptr implementation details -*- 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 bits/shared_ptr_base.h 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_BASE_H 00050 #define _SHARED_PTR_BASE_H 1 00051 00052 #include <typeinfo> 00053 #include <bits/allocated_ptr.h> 00054 #include <bits/refwrap.h> 00055 #include <bits/stl_function.h> 00056 #include <ext/aligned_buffer.h> 00057 00058 namespace std _GLIBCXX_VISIBILITY(default) 00059 { 00060 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00061 00062 #if _GLIBCXX_USE_DEPRECATED 00063 #pragma GCC diagnostic push 00064 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00065 template<typename> class auto_ptr; 00066 #pragma GCC diagnostic pop 00067 #endif 00068 00069 /** 00070 * @brief Exception possibly thrown by @c shared_ptr. 00071 * @ingroup exceptions 00072 */ 00073 class bad_weak_ptr : public std::exception 00074 { 00075 public: 00076 virtual char const* what() const noexcept; 00077 00078 virtual ~bad_weak_ptr() noexcept; 00079 }; 00080 00081 // Substitute for bad_weak_ptr object in the case of -fno-exceptions. 00082 inline void 00083 __throw_bad_weak_ptr() 00084 { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); } 00085 00086 using __gnu_cxx::_Lock_policy; 00087 using __gnu_cxx::__default_lock_policy; 00088 using __gnu_cxx::_S_single; 00089 using __gnu_cxx::_S_mutex; 00090 using __gnu_cxx::_S_atomic; 00091 00092 // Empty helper class except when the template argument is _S_mutex. 00093 template<_Lock_policy _Lp> 00094 class _Mutex_base 00095 { 00096 protected: 00097 // The atomic policy uses fully-fenced builtins, single doesn't care. 00098 enum { _S_need_barriers = 0 }; 00099 }; 00100 00101 template<> 00102 class _Mutex_base<_S_mutex> 00103 : public __gnu_cxx::__mutex 00104 { 00105 protected: 00106 // This policy is used when atomic builtins are not available. 00107 // The replacement atomic operations might not have the necessary 00108 // memory barriers. 00109 enum { _S_need_barriers = 1 }; 00110 }; 00111 00112 template<_Lock_policy _Lp = __default_lock_policy> 00113 class _Sp_counted_base 00114 : public _Mutex_base<_Lp> 00115 { 00116 public: 00117 _Sp_counted_base() noexcept 00118 : _M_use_count(1), _M_weak_count(1) { } 00119 00120 virtual 00121 ~_Sp_counted_base() noexcept 00122 { } 00123 00124 // Called when _M_use_count drops to zero, to release the resources 00125 // managed by *this. 00126 virtual void 00127 _M_dispose() noexcept = 0; 00128 00129 // Called when _M_weak_count drops to zero. 00130 virtual void 00131 _M_destroy() noexcept 00132 { delete this; } 00133 00134 virtual void* 00135 _M_get_deleter(const std::type_info&) noexcept = 0; 00136 00137 void 00138 _M_add_ref_copy() 00139 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } 00140 00141 void 00142 _M_add_ref_lock(); 00143 00144 bool 00145 _M_add_ref_lock_nothrow(); 00146 00147 void 00148 _M_release() noexcept 00149 { 00150 // Be race-detector-friendly. For more info see bits/c++config. 00151 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); 00152 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) 00153 { 00154 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); 00155 _M_dispose(); 00156 // There must be a memory barrier between dispose() and destroy() 00157 // to ensure that the effects of dispose() are observed in the 00158 // thread that runs destroy(). 00159 // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html 00160 if (_Mutex_base<_Lp>::_S_need_barriers) 00161 { 00162 __atomic_thread_fence (__ATOMIC_ACQ_REL); 00163 } 00164 00165 // Be race-detector-friendly. For more info see bits/c++config. 00166 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 00167 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, 00168 -1) == 1) 00169 { 00170 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 00171 _M_destroy(); 00172 } 00173 } 00174 } 00175 00176 void 00177 _M_weak_add_ref() noexcept 00178 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } 00179 00180 void 00181 _M_weak_release() noexcept 00182 { 00183 // Be race-detector-friendly. For more info see bits/c++config. 00184 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 00185 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) 00186 { 00187 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 00188 if (_Mutex_base<_Lp>::_S_need_barriers) 00189 { 00190 // See _M_release(), 00191 // destroy() must observe results of dispose() 00192 __atomic_thread_fence (__ATOMIC_ACQ_REL); 00193 } 00194 _M_destroy(); 00195 } 00196 } 00197 00198 long 00199 _M_get_use_count() const noexcept 00200 { 00201 // No memory barrier is used here so there is no synchronization 00202 // with other threads. 00203 return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED); 00204 } 00205 00206 private: 00207 _Sp_counted_base(_Sp_counted_base const&) = delete; 00208 _Sp_counted_base& operator=(_Sp_counted_base const&) = delete; 00209 00210 _Atomic_word _M_use_count; // #shared 00211 _Atomic_word _M_weak_count; // #weak + (#shared != 0) 00212 }; 00213 00214 template<> 00215 inline void 00216 _Sp_counted_base<_S_single>:: 00217 _M_add_ref_lock() 00218 { 00219 if (_M_use_count == 0) 00220 __throw_bad_weak_ptr(); 00221 ++_M_use_count; 00222 } 00223 00224 template<> 00225 inline void 00226 _Sp_counted_base<_S_mutex>:: 00227 _M_add_ref_lock() 00228 { 00229 __gnu_cxx::__scoped_lock sentry(*this); 00230 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 00231 { 00232 _M_use_count = 0; 00233 __throw_bad_weak_ptr(); 00234 } 00235 } 00236 00237 template<> 00238 inline void 00239 _Sp_counted_base<_S_atomic>:: 00240 _M_add_ref_lock() 00241 { 00242 // Perform lock-free add-if-not-zero operation. 00243 _Atomic_word __count = _M_get_use_count(); 00244 do 00245 { 00246 if (__count == 0) 00247 __throw_bad_weak_ptr(); 00248 // Replace the current counter value with the old value + 1, as 00249 // long as it's not changed meanwhile. 00250 } 00251 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, 00252 true, __ATOMIC_ACQ_REL, 00253 __ATOMIC_RELAXED)); 00254 } 00255 00256 template<> 00257 inline bool 00258 _Sp_counted_base<_S_single>:: 00259 _M_add_ref_lock_nothrow() 00260 { 00261 if (_M_use_count == 0) 00262 return false; 00263 ++_M_use_count; 00264 return true; 00265 } 00266 00267 template<> 00268 inline bool 00269 _Sp_counted_base<_S_mutex>:: 00270 _M_add_ref_lock_nothrow() 00271 { 00272 __gnu_cxx::__scoped_lock sentry(*this); 00273 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 00274 { 00275 _M_use_count = 0; 00276 return false; 00277 } 00278 return true; 00279 } 00280 00281 template<> 00282 inline bool 00283 _Sp_counted_base<_S_atomic>:: 00284 _M_add_ref_lock_nothrow() 00285 { 00286 // Perform lock-free add-if-not-zero operation. 00287 _Atomic_word __count = _M_get_use_count(); 00288 do 00289 { 00290 if (__count == 0) 00291 return false; 00292 // Replace the current counter value with the old value + 1, as 00293 // long as it's not changed meanwhile. 00294 } 00295 while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, 00296 true, __ATOMIC_ACQ_REL, 00297 __ATOMIC_RELAXED)); 00298 return true; 00299 } 00300 00301 template<> 00302 inline void 00303 _Sp_counted_base<_S_single>::_M_add_ref_copy() 00304 { ++_M_use_count; } 00305 00306 template<> 00307 inline void 00308 _Sp_counted_base<_S_single>::_M_release() noexcept 00309 { 00310 if (--_M_use_count == 0) 00311 { 00312 _M_dispose(); 00313 if (--_M_weak_count == 0) 00314 _M_destroy(); 00315 } 00316 } 00317 00318 template<> 00319 inline void 00320 _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept 00321 { ++_M_weak_count; } 00322 00323 template<> 00324 inline void 00325 _Sp_counted_base<_S_single>::_M_weak_release() noexcept 00326 { 00327 if (--_M_weak_count == 0) 00328 _M_destroy(); 00329 } 00330 00331 template<> 00332 inline long 00333 _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept 00334 { return _M_use_count; } 00335 00336 00337 // Forward declarations. 00338 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 00339 class __shared_ptr; 00340 00341 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 00342 class __weak_ptr; 00343 00344 template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 00345 class __enable_shared_from_this; 00346 00347 template<typename _Tp> 00348 class shared_ptr; 00349 00350 template<typename _Tp> 00351 class weak_ptr; 00352 00353 template<typename _Tp> 00354 struct owner_less; 00355 00356 template<typename _Tp> 00357 class enable_shared_from_this; 00358 00359 template<_Lock_policy _Lp = __default_lock_policy> 00360 class __weak_count; 00361 00362 template<_Lock_policy _Lp = __default_lock_policy> 00363 class __shared_count; 00364 00365 00366 // Counted ptr with no deleter or allocator support 00367 template<typename _Ptr, _Lock_policy _Lp> 00368 class _Sp_counted_ptr final : public _Sp_counted_base<_Lp> 00369 { 00370 public: 00371 explicit 00372 _Sp_counted_ptr(_Ptr __p) noexcept 00373 : _M_ptr(__p) { } 00374 00375 virtual void 00376 _M_dispose() noexcept 00377 { delete _M_ptr; } 00378 00379 virtual void 00380 _M_destroy() noexcept 00381 { delete this; } 00382 00383 virtual void* 00384 _M_get_deleter(const std::type_info&) noexcept 00385 { return nullptr; } 00386 00387 _Sp_counted_ptr(const _Sp_counted_ptr&) = delete; 00388 _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete; 00389 00390 private: 00391 _Ptr _M_ptr; 00392 }; 00393 00394 template<> 00395 inline void 00396 _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { } 00397 00398 template<> 00399 inline void 00400 _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { } 00401 00402 template<> 00403 inline void 00404 _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { } 00405 00406 template<int _Nm, typename _Tp, 00407 bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)> 00408 struct _Sp_ebo_helper; 00409 00410 /// Specialization using EBO. 00411 template<int _Nm, typename _Tp> 00412 struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp 00413 { 00414 explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { } 00415 explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { } 00416 00417 static _Tp& 00418 _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); } 00419 }; 00420 00421 /// Specialization not using EBO. 00422 template<int _Nm, typename _Tp> 00423 struct _Sp_ebo_helper<_Nm, _Tp, false> 00424 { 00425 explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { } 00426 explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(std::move(__tp)) { } 00427 00428 static _Tp& 00429 _S_get(_Sp_ebo_helper& __eboh) 00430 { return __eboh._M_tp; } 00431 00432 private: 00433 _Tp _M_tp; 00434 }; 00435 00436 // Support for custom deleter and/or allocator 00437 template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp> 00438 class _Sp_counted_deleter final : public _Sp_counted_base<_Lp> 00439 { 00440 class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc> 00441 { 00442 typedef _Sp_ebo_helper<0, _Deleter> _Del_base; 00443 typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base; 00444 00445 public: 00446 _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept 00447 : _M_ptr(__p), _Del_base(std::move(__d)), _Alloc_base(__a) 00448 { } 00449 00450 _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); } 00451 _Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); } 00452 00453 _Ptr _M_ptr; 00454 }; 00455 00456 public: 00457 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>; 00458 00459 // __d(__p) must not throw. 00460 _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept 00461 : _M_impl(__p, std::move(__d), _Alloc()) { } 00462 00463 // __d(__p) must not throw. 00464 _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept 00465 : _M_impl(__p, std::move(__d), __a) { } 00466 00467 ~_Sp_counted_deleter() noexcept { } 00468 00469 virtual void 00470 _M_dispose() noexcept 00471 { _M_impl._M_del()(_M_impl._M_ptr); } 00472 00473 virtual void 00474 _M_destroy() noexcept 00475 { 00476 __allocator_type __a(_M_impl._M_alloc()); 00477 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; 00478 this->~_Sp_counted_deleter(); 00479 } 00480 00481 virtual void* 00482 _M_get_deleter(const std::type_info& __ti) noexcept 00483 { 00484 #if __cpp_rtti 00485 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00486 // 2400. shared_ptr's get_deleter() should use addressof() 00487 return __ti == typeid(_Deleter) 00488 ? std::__addressof(_M_impl._M_del()) 00489 : nullptr; 00490 #else 00491 return nullptr; 00492 #endif 00493 } 00494 00495 private: 00496 _Impl _M_impl; 00497 }; 00498 00499 // helpers for make_shared / allocate_shared 00500 00501 struct _Sp_make_shared_tag 00502 { 00503 private: 00504 template<typename _Tp, typename _Alloc, _Lock_policy _Lp> 00505 friend class _Sp_counted_ptr_inplace; 00506 00507 static const type_info& 00508 _S_ti() noexcept _GLIBCXX_VISIBILITY(default) 00509 { 00510 alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { }; 00511 return reinterpret_cast<const type_info&>(__tag); 00512 } 00513 }; 00514 00515 template<typename _Alloc> 00516 struct _Sp_alloc_shared_tag 00517 { 00518 const _Alloc& _M_a; 00519 }; 00520 00521 template<typename _Tp, typename _Alloc, _Lock_policy _Lp> 00522 class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> 00523 { 00524 class _Impl : _Sp_ebo_helper<0, _Alloc> 00525 { 00526 typedef _Sp_ebo_helper<0, _Alloc> _A_base; 00527 00528 public: 00529 explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { } 00530 00531 _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); } 00532 00533 __gnu_cxx::__aligned_buffer<_Tp> _M_storage; 00534 }; 00535 00536 public: 00537 using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>; 00538 00539 template<typename... _Args> 00540 _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args) 00541 : _M_impl(__a) 00542 { 00543 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00544 // 2070. allocate_shared should use allocator_traits<A>::construct 00545 allocator_traits<_Alloc>::construct(__a, _M_ptr(), 00546 std::forward<_Args>(__args)...); // might throw 00547 } 00548 00549 ~_Sp_counted_ptr_inplace() noexcept { } 00550 00551 virtual void 00552 _M_dispose() noexcept 00553 { 00554 allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr()); 00555 } 00556 00557 // Override because the allocator needs to know the dynamic type 00558 virtual void 00559 _M_destroy() noexcept 00560 { 00561 __allocator_type __a(_M_impl._M_alloc()); 00562 __allocated_ptr<__allocator_type> __guard_ptr{ __a, this }; 00563 this->~_Sp_counted_ptr_inplace(); 00564 } 00565 00566 private: 00567 friend class __shared_count<_Lp>; // To be able to call _M_ptr(). 00568 00569 // No longer used, but code compiled against old libstdc++ headers 00570 // might still call it from __shared_ptr ctor to get the pointer out. 00571 virtual void* 00572 _M_get_deleter(const std::type_info& __ti) noexcept override 00573 { 00574 // Check for the fake type_info first, so we don't try to access it 00575 // as a real type_info object. 00576 if (&__ti == &_Sp_make_shared_tag::_S_ti()) 00577 return const_cast<typename remove_cv<_Tp>::type*>(_M_ptr()); 00578 #if __cpp_rtti 00579 // Callers compiled with old libstdc++ headers and RTTI enabled 00580 // might pass this instead: 00581 else if (__ti == typeid(_Sp_make_shared_tag)) 00582 return const_cast<typename remove_cv<_Tp>::type*>(_M_ptr()); 00583 #else 00584 // Cannot detect a real type_info object. If the linker keeps a 00585 // definition of this function compiled with -fno-rtti then callers 00586 // that have RTTI enabled and pass a real type_info object will get 00587 // a null pointer returned. 00588 #endif 00589 return nullptr; 00590 } 00591 00592 _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); } 00593 00594 _Impl _M_impl; 00595 }; 00596 00597 // The default deleter for shared_ptr<T[]> and shared_ptr<T[N]>. 00598 struct __sp_array_delete 00599 { 00600 template<typename _Yp> 00601 void operator()(_Yp* __p) const { delete[] __p; } 00602 }; 00603 00604 template<_Lock_policy _Lp> 00605 class __shared_count 00606 { 00607 template<typename _Tp> 00608 struct __not_alloc_shared_tag { using type = void; }; 00609 00610 template<typename _Tp> 00611 struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { }; 00612 00613 public: 00614 constexpr __shared_count() noexcept : _M_pi(0) 00615 { } 00616 00617 template<typename _Ptr> 00618 explicit 00619 __shared_count(_Ptr __p) : _M_pi(0) 00620 { 00621 __try 00622 { 00623 _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); 00624 } 00625 __catch(...) 00626 { 00627 delete __p; 00628 __throw_exception_again; 00629 } 00630 } 00631 00632 template<typename _Ptr> 00633 __shared_count(_Ptr __p, /* is_array = */ false_type) 00634 : __shared_count(__p) 00635 { } 00636 00637 template<typename _Ptr> 00638 __shared_count(_Ptr __p, /* is_array = */ true_type) 00639 : __shared_count(__p, __sp_array_delete{}, allocator<void>()) 00640 { } 00641 00642 template<typename _Ptr, typename _Deleter, 00643 typename = typename __not_alloc_shared_tag<_Deleter>::type> 00644 __shared_count(_Ptr __p, _Deleter __d) 00645 : __shared_count(__p, std::move(__d), allocator<void>()) 00646 { } 00647 00648 template<typename _Ptr, typename _Deleter, typename _Alloc, 00649 typename = typename __not_alloc_shared_tag<_Deleter>::type> 00650 __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) 00651 { 00652 typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; 00653 __try 00654 { 00655 typename _Sp_cd_type::__allocator_type __a2(__a); 00656 auto __guard = std::__allocate_guarded(__a2); 00657 _Sp_cd_type* __mem = __guard.get(); 00658 ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a)); 00659 _M_pi = __mem; 00660 __guard = nullptr; 00661 } 00662 __catch(...) 00663 { 00664 __d(__p); // Call _Deleter on __p. 00665 __throw_exception_again; 00666 } 00667 } 00668 00669 template<typename _Tp, typename _Alloc, typename... _Args> 00670 __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a, 00671 _Args&&... __args) 00672 { 00673 typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type; 00674 typename _Sp_cp_type::__allocator_type __a2(__a._M_a); 00675 auto __guard = std::__allocate_guarded(__a2); 00676 _Sp_cp_type* __mem = __guard.get(); 00677 auto __pi = ::new (__mem) 00678 _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...); 00679 __guard = nullptr; 00680 _M_pi = __pi; 00681 __p = __pi->_M_ptr(); 00682 } 00683 00684 #if _GLIBCXX_USE_DEPRECATED 00685 #pragma GCC diagnostic push 00686 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 00687 // Special case for auto_ptr<_Tp> to provide the strong guarantee. 00688 template<typename _Tp> 00689 explicit 00690 __shared_count(std::auto_ptr<_Tp>&& __r); 00691 #pragma GCC diagnostic pop 00692 #endif 00693 00694 // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee. 00695 template<typename _Tp, typename _Del> 00696 explicit 00697 __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0) 00698 { 00699 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00700 // 2415. Inconsistency between unique_ptr and shared_ptr 00701 if (__r.get() == nullptr) 00702 return; 00703 00704 using _Ptr = typename unique_ptr<_Tp, _Del>::pointer; 00705 using _Del2 = typename conditional<is_reference<_Del>::value, 00706 reference_wrapper<typename remove_reference<_Del>::type>, 00707 _Del>::type; 00708 using _Sp_cd_type 00709 = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>; 00710 using _Alloc = allocator<_Sp_cd_type>; 00711 using _Alloc_traits = allocator_traits<_Alloc>; 00712 _Alloc __a; 00713 _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1); 00714 _Alloc_traits::construct(__a, __mem, __r.release(), 00715 __r.get_deleter()); // non-throwing 00716 _M_pi = __mem; 00717 } 00718 00719 // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 00720 explicit __shared_count(const __weak_count<_Lp>& __r); 00721 00722 // Does not throw if __r._M_get_use_count() == 0, caller must check. 00723 explicit __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t); 00724 00725 ~__shared_count() noexcept 00726 { 00727 if (_M_pi != nullptr) 00728 _M_pi->_M_release(); 00729 } 00730 00731 __shared_count(const __shared_count& __r) noexcept 00732 : _M_pi(__r._M_pi) 00733 { 00734 if (_M_pi != 0) 00735 _M_pi->_M_add_ref_copy(); 00736 } 00737 00738 __shared_count& 00739 operator=(const __shared_count& __r) noexcept 00740 { 00741 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00742 if (__tmp != _M_pi) 00743 { 00744 if (__tmp != 0) 00745 __tmp->_M_add_ref_copy(); 00746 if (_M_pi != 0) 00747 _M_pi->_M_release(); 00748 _M_pi = __tmp; 00749 } 00750 return *this; 00751 } 00752 00753 void 00754 _M_swap(__shared_count& __r) noexcept 00755 { 00756 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00757 __r._M_pi = _M_pi; 00758 _M_pi = __tmp; 00759 } 00760 00761 long 00762 _M_get_use_count() const noexcept 00763 { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 00764 00765 bool 00766 _M_unique() const noexcept 00767 { return this->_M_get_use_count() == 1; } 00768 00769 void* 00770 _M_get_deleter(const std::type_info& __ti) const noexcept 00771 { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; } 00772 00773 bool 00774 _M_less(const __shared_count& __rhs) const noexcept 00775 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00776 00777 bool 00778 _M_less(const __weak_count<_Lp>& __rhs) const noexcept 00779 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00780 00781 // Friend function injected into enclosing namespace and found by ADL 00782 friend inline bool 00783 operator==(const __shared_count& __a, const __shared_count& __b) noexcept 00784 { return __a._M_pi == __b._M_pi; } 00785 00786 private: 00787 friend class __weak_count<_Lp>; 00788 00789 _Sp_counted_base<_Lp>* _M_pi; 00790 }; 00791 00792 00793 template<_Lock_policy _Lp> 00794 class __weak_count 00795 { 00796 public: 00797 constexpr __weak_count() noexcept : _M_pi(nullptr) 00798 { } 00799 00800 __weak_count(const __shared_count<_Lp>& __r) noexcept 00801 : _M_pi(__r._M_pi) 00802 { 00803 if (_M_pi != nullptr) 00804 _M_pi->_M_weak_add_ref(); 00805 } 00806 00807 __weak_count(const __weak_count& __r) noexcept 00808 : _M_pi(__r._M_pi) 00809 { 00810 if (_M_pi != nullptr) 00811 _M_pi->_M_weak_add_ref(); 00812 } 00813 00814 __weak_count(__weak_count&& __r) noexcept 00815 : _M_pi(__r._M_pi) 00816 { __r._M_pi = nullptr; } 00817 00818 ~__weak_count() noexcept 00819 { 00820 if (_M_pi != nullptr) 00821 _M_pi->_M_weak_release(); 00822 } 00823 00824 __weak_count& 00825 operator=(const __shared_count<_Lp>& __r) noexcept 00826 { 00827 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00828 if (__tmp != nullptr) 00829 __tmp->_M_weak_add_ref(); 00830 if (_M_pi != nullptr) 00831 _M_pi->_M_weak_release(); 00832 _M_pi = __tmp; 00833 return *this; 00834 } 00835 00836 __weak_count& 00837 operator=(const __weak_count& __r) noexcept 00838 { 00839 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00840 if (__tmp != nullptr) 00841 __tmp->_M_weak_add_ref(); 00842 if (_M_pi != nullptr) 00843 _M_pi->_M_weak_release(); 00844 _M_pi = __tmp; 00845 return *this; 00846 } 00847 00848 __weak_count& 00849 operator=(__weak_count&& __r) noexcept 00850 { 00851 if (_M_pi != nullptr) 00852 _M_pi->_M_weak_release(); 00853 _M_pi = __r._M_pi; 00854 __r._M_pi = nullptr; 00855 return *this; 00856 } 00857 00858 void 00859 _M_swap(__weak_count& __r) noexcept 00860 { 00861 _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 00862 __r._M_pi = _M_pi; 00863 _M_pi = __tmp; 00864 } 00865 00866 long 00867 _M_get_use_count() const noexcept 00868 { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; } 00869 00870 bool 00871 _M_less(const __weak_count& __rhs) const noexcept 00872 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00873 00874 bool 00875 _M_less(const __shared_count<_Lp>& __rhs) const noexcept 00876 { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 00877 00878 // Friend function injected into enclosing namespace and found by ADL 00879 friend inline bool 00880 operator==(const __weak_count& __a, const __weak_count& __b) noexcept 00881 { return __a._M_pi == __b._M_pi; } 00882 00883 private: 00884 friend class __shared_count<_Lp>; 00885 00886 _Sp_counted_base<_Lp>* _M_pi; 00887 }; 00888 00889 // Now that __weak_count is defined we can define this constructor: 00890 template<_Lock_policy _Lp> 00891 inline 00892 __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r) 00893 : _M_pi(__r._M_pi) 00894 { 00895 if (_M_pi != nullptr) 00896 _M_pi->_M_add_ref_lock(); 00897 else 00898 __throw_bad_weak_ptr(); 00899 } 00900 00901 // Now that __weak_count is defined we can define this constructor: 00902 template<_Lock_policy _Lp> 00903 inline 00904 __shared_count<_Lp>:: 00905 __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) 00906 : _M_pi(__r._M_pi) 00907 { 00908 if (_M_pi != nullptr) 00909 if (!_M_pi->_M_add_ref_lock_nothrow()) 00910 _M_pi = nullptr; 00911 } 00912 00913 #define __cpp_lib_shared_ptr_arrays 201603 00914 00915 // Helper traits for shared_ptr of array: 00916 00917 // A pointer type Y* is said to be compatible with a pointer type T* when 00918 // either Y* is convertible to T* or Y is U[N] and T is U cv []. 00919 template<typename _Yp_ptr, typename _Tp_ptr> 00920 struct __sp_compatible_with 00921 : false_type 00922 { }; 00923 00924 template<typename _Yp, typename _Tp> 00925 struct __sp_compatible_with<_Yp*, _Tp*> 00926 : is_convertible<_Yp*, _Tp*>::type 00927 { }; 00928 00929 template<typename _Up, size_t _Nm> 00930 struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]> 00931 : true_type 00932 { }; 00933 00934 template<typename _Up, size_t _Nm> 00935 struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]> 00936 : true_type 00937 { }; 00938 00939 template<typename _Up, size_t _Nm> 00940 struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]> 00941 : true_type 00942 { }; 00943 00944 template<typename _Up, size_t _Nm> 00945 struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]> 00946 : true_type 00947 { }; 00948 00949 // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N]. 00950 template<typename _Up, size_t _Nm, typename _Yp, typename = void> 00951 struct __sp_is_constructible_arrN 00952 : false_type 00953 { }; 00954 00955 template<typename _Up, size_t _Nm, typename _Yp> 00956 struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>> 00957 : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type 00958 { }; 00959 00960 // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[]. 00961 template<typename _Up, typename _Yp, typename = void> 00962 struct __sp_is_constructible_arr 00963 : false_type 00964 { }; 00965 00966 template<typename _Up, typename _Yp> 00967 struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>> 00968 : is_convertible<_Yp(*)[], _Up(*)[]>::type 00969 { }; 00970 00971 // Trait to check if shared_ptr<T> can be constructed from Y*. 00972 template<typename _Tp, typename _Yp> 00973 struct __sp_is_constructible; 00974 00975 // When T is U[N], Y(*)[N] shall be convertible to T*; 00976 template<typename _Up, size_t _Nm, typename _Yp> 00977 struct __sp_is_constructible<_Up[_Nm], _Yp> 00978 : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type 00979 { }; 00980 00981 // when T is U[], Y(*)[] shall be convertible to T*; 00982 template<typename _Up, typename _Yp> 00983 struct __sp_is_constructible<_Up[], _Yp> 00984 : __sp_is_constructible_arr<_Up, _Yp>::type 00985 { }; 00986 00987 // otherwise, Y* shall be convertible to T*. 00988 template<typename _Tp, typename _Yp> 00989 struct __sp_is_constructible 00990 : is_convertible<_Yp*, _Tp*>::type 00991 { }; 00992 00993 00994 // Define operator* and operator-> for shared_ptr<T>. 00995 template<typename _Tp, _Lock_policy _Lp, 00996 bool = is_array<_Tp>::value, bool = is_void<_Tp>::value> 00997 class __shared_ptr_access 00998 { 00999 public: 01000 using element_type = _Tp; 01001 01002 element_type& 01003 operator*() const noexcept 01004 { 01005 __glibcxx_assert(_M_get() != nullptr); 01006 return *_M_get(); 01007 } 01008 01009 element_type* 01010 operator->() const noexcept 01011 { 01012 _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr); 01013 return _M_get(); 01014 } 01015 01016 private: 01017 element_type* 01018 _M_get() const noexcept 01019 { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); } 01020 }; 01021 01022 // Define operator-> for shared_ptr<cv void>. 01023 template<typename _Tp, _Lock_policy _Lp> 01024 class __shared_ptr_access<_Tp, _Lp, false, true> 01025 { 01026 public: 01027 using element_type = _Tp; 01028 01029 element_type* 01030 operator->() const noexcept 01031 { 01032 auto __ptr = static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); 01033 _GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr); 01034 return __ptr; 01035 } 01036 }; 01037 01038 // Define operator[] for shared_ptr<T[]> and shared_ptr<T[N]>. 01039 template<typename _Tp, _Lock_policy _Lp> 01040 class __shared_ptr_access<_Tp, _Lp, true, false> 01041 { 01042 public: 01043 using element_type = typename remove_extent<_Tp>::type; 01044 01045 #if __cplusplus <= 201402L 01046 [[__deprecated__("shared_ptr<T[]>::operator* is absent from C++17")]] 01047 element_type& 01048 operator*() const noexcept 01049 { 01050 __glibcxx_assert(_M_get() != nullptr); 01051 return *_M_get(); 01052 } 01053 01054 [[__deprecated__("shared_ptr<T[]>::operator-> is absent from C++17")]] 01055 element_type* 01056 operator->() const noexcept 01057 { 01058 _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr); 01059 return _M_get(); 01060 } 01061 #endif 01062 01063 element_type& 01064 operator[](ptrdiff_t __i) const 01065 { 01066 __glibcxx_assert(_M_get() != nullptr); 01067 __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value); 01068 return _M_get()[__i]; 01069 } 01070 01071 private: 01072 element_type* 01073 _M_get() const noexcept 01074 { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); } 01075 }; 01076 01077 template<typename _Tp, _Lock_policy _Lp> 01078 class __shared_ptr 01079 : public __shared_ptr_access<_Tp, _Lp> 01080 { 01081 public: 01082 using element_type = typename remove_extent<_Tp>::type; 01083 01084 private: 01085 // Constraint for taking ownership of a pointer of type _Yp*: 01086 template<typename _Yp> 01087 using _SafeConv 01088 = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type; 01089 01090 // Constraint for construction from shared_ptr and weak_ptr: 01091 template<typename _Yp, typename _Res = void> 01092 using _Compatible = typename 01093 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type; 01094 01095 // Constraint for assignment from shared_ptr and weak_ptr: 01096 template<typename _Yp> 01097 using _Assignable = _Compatible<_Yp, __shared_ptr&>; 01098 01099 // Constraint for construction from unique_ptr: 01100 template<typename _Yp, typename _Del, typename _Res = void, 01101 typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer> 01102 using _UniqCompatible = typename enable_if<__and_< 01103 __sp_compatible_with<_Yp*, _Tp*>, is_convertible<_Ptr, element_type*> 01104 >::value, _Res>::type; 01105 01106 // Constraint for assignment from unique_ptr: 01107 template<typename _Yp, typename _Del> 01108 using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>; 01109 01110 public: 01111 01112 #if __cplusplus > 201402L 01113 using weak_type = __weak_ptr<_Tp, _Lp>; 01114 #endif 01115 01116 constexpr __shared_ptr() noexcept 01117 : _M_ptr(0), _M_refcount() 01118 { } 01119 01120 template<typename _Yp, typename = _SafeConv<_Yp>> 01121 explicit 01122 __shared_ptr(_Yp* __p) 01123 : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type()) 01124 { 01125 static_assert( !is_void<_Yp>::value, "incomplete type" ); 01126 static_assert( sizeof(_Yp) > 0, "incomplete type" ); 01127 _M_enable_shared_from_this_with(__p); 01128 } 01129 01130 template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>> 01131 __shared_ptr(_Yp* __p, _Deleter __d) 01132 : _M_ptr(__p), _M_refcount(__p, std::move(__d)) 01133 { 01134 static_assert(__is_invocable<_Deleter&, _Yp*&>::value, 01135 "deleter expression d(p) is well-formed"); 01136 _M_enable_shared_from_this_with(__p); 01137 } 01138 01139 template<typename _Yp, typename _Deleter, typename _Alloc, 01140 typename = _SafeConv<_Yp>> 01141 __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a) 01142 : _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a)) 01143 { 01144 static_assert(__is_invocable<_Deleter&, _Yp*&>::value, 01145 "deleter expression d(p) is well-formed"); 01146 _M_enable_shared_from_this_with(__p); 01147 } 01148 01149 template<typename _Deleter> 01150 __shared_ptr(nullptr_t __p, _Deleter __d) 01151 : _M_ptr(0), _M_refcount(__p, std::move(__d)) 01152 { } 01153 01154 template<typename _Deleter, typename _Alloc> 01155 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 01156 : _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a)) 01157 { } 01158 01159 template<typename _Yp> 01160 __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r, 01161 element_type* __p) noexcept 01162 : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws 01163 { } 01164 01165 __shared_ptr(const __shared_ptr&) noexcept = default; 01166 __shared_ptr& operator=(const __shared_ptr&) noexcept = default; 01167 ~__shared_ptr() = default; 01168 01169 template<typename _Yp, typename = _Compatible<_Yp>> 01170 __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept 01171 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 01172 { } 01173 01174 __shared_ptr(__shared_ptr&& __r) noexcept 01175 : _M_ptr(__r._M_ptr), _M_refcount() 01176 { 01177 _M_refcount._M_swap(__r._M_refcount); 01178 __r._M_ptr = 0; 01179 } 01180 01181 template<typename _Yp, typename = _Compatible<_Yp>> 01182 __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept 01183 : _M_ptr(__r._M_ptr), _M_refcount() 01184 { 01185 _M_refcount._M_swap(__r._M_refcount); 01186 __r._M_ptr = 0; 01187 } 01188 01189 template<typename _Yp, typename = _Compatible<_Yp>> 01190 explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r) 01191 : _M_refcount(__r._M_refcount) // may throw 01192 { 01193 // It is now safe to copy __r._M_ptr, as 01194 // _M_refcount(__r._M_refcount) did not throw. 01195 _M_ptr = __r._M_ptr; 01196 } 01197 01198 // If an exception is thrown this constructor has no effect. 01199 template<typename _Yp, typename _Del, 01200 typename = _UniqCompatible<_Yp, _Del>> 01201 __shared_ptr(unique_ptr<_Yp, _Del>&& __r) 01202 : _M_ptr(__r.get()), _M_refcount() 01203 { 01204 auto __raw = __to_address(__r.get()); 01205 _M_refcount = __shared_count<_Lp>(std::move(__r)); 01206 _M_enable_shared_from_this_with(__raw); 01207 } 01208 01209 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED 01210 protected: 01211 // If an exception is thrown this constructor has no effect. 01212 template<typename _Tp1, typename _Del, 01213 typename enable_if<__and_< 01214 __not_<is_array<_Tp>>, is_array<_Tp1>, 01215 is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*> 01216 >::value, bool>::type = true> 01217 __shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete) 01218 : _M_ptr(__r.get()), _M_refcount() 01219 { 01220 auto __raw = __to_address(__r.get()); 01221 _M_refcount = __shared_count<_Lp>(std::move(__r)); 01222 _M_enable_shared_from_this_with(__raw); 01223 } 01224 public: 01225 #endif 01226 01227 #if _GLIBCXX_USE_DEPRECATED 01228 #pragma GCC diagnostic push 01229 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 01230 // Postcondition: use_count() == 1 and __r.get() == 0 01231 template<typename _Yp, typename = _Compatible<_Yp>> 01232 __shared_ptr(auto_ptr<_Yp>&& __r); 01233 #pragma GCC diagnostic pop 01234 #endif 01235 01236 constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { } 01237 01238 template<typename _Yp> 01239 _Assignable<_Yp> 01240 operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept 01241 { 01242 _M_ptr = __r._M_ptr; 01243 _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 01244 return *this; 01245 } 01246 01247 #if _GLIBCXX_USE_DEPRECATED 01248 #pragma GCC diagnostic push 01249 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 01250 template<typename _Yp> 01251 _Assignable<_Yp> 01252 operator=(auto_ptr<_Yp>&& __r) 01253 { 01254 __shared_ptr(std::move(__r)).swap(*this); 01255 return *this; 01256 } 01257 #pragma GCC diagnostic pop 01258 #endif 01259 01260 __shared_ptr& 01261 operator=(__shared_ptr&& __r) noexcept 01262 { 01263 __shared_ptr(std::move(__r)).swap(*this); 01264 return *this; 01265 } 01266 01267 template<class _Yp> 01268 _Assignable<_Yp> 01269 operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept 01270 { 01271 __shared_ptr(std::move(__r)).swap(*this); 01272 return *this; 01273 } 01274 01275 template<typename _Yp, typename _Del> 01276 _UniqAssignable<_Yp, _Del> 01277 operator=(unique_ptr<_Yp, _Del>&& __r) 01278 { 01279 __shared_ptr(std::move(__r)).swap(*this); 01280 return *this; 01281 } 01282 01283 void 01284 reset() noexcept 01285 { __shared_ptr().swap(*this); } 01286 01287 template<typename _Yp> 01288 _SafeConv<_Yp> 01289 reset(_Yp* __p) // _Yp must be complete. 01290 { 01291 // Catch self-reset errors. 01292 __glibcxx_assert(__p == 0 || __p != _M_ptr); 01293 __shared_ptr(__p).swap(*this); 01294 } 01295 01296 template<typename _Yp, typename _Deleter> 01297 _SafeConv<_Yp> 01298 reset(_Yp* __p, _Deleter __d) 01299 { __shared_ptr(__p, std::move(__d)).swap(*this); } 01300 01301 template<typename _Yp, typename _Deleter, typename _Alloc> 01302 _SafeConv<_Yp> 01303 reset(_Yp* __p, _Deleter __d, _Alloc __a) 01304 { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); } 01305 01306 element_type* 01307 get() const noexcept 01308 { return _M_ptr; } 01309 01310 explicit operator bool() const // never throws 01311 { return _M_ptr == 0 ? false : true; } 01312 01313 bool 01314 unique() const noexcept 01315 { return _M_refcount._M_unique(); } 01316 01317 long 01318 use_count() const noexcept 01319 { return _M_refcount._M_get_use_count(); } 01320 01321 void 01322 swap(__shared_ptr<_Tp, _Lp>& __other) noexcept 01323 { 01324 std::swap(_M_ptr, __other._M_ptr); 01325 _M_refcount._M_swap(__other._M_refcount); 01326 } 01327 01328 template<typename _Tp1> 01329 bool 01330 owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept 01331 { return _M_refcount._M_less(__rhs._M_refcount); } 01332 01333 template<typename _Tp1> 01334 bool 01335 owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept 01336 { return _M_refcount._M_less(__rhs._M_refcount); } 01337 01338 protected: 01339 // This constructor is non-standard, it is used by allocate_shared. 01340 template<typename _Alloc, typename... _Args> 01341 __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) 01342 : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...) 01343 { _M_enable_shared_from_this_with(_M_ptr); } 01344 01345 template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc, 01346 typename... _Args> 01347 friend __shared_ptr<_Tp1, _Lp1> 01348 __allocate_shared(const _Alloc& __a, _Args&&... __args); 01349 01350 // This constructor is used by __weak_ptr::lock() and 01351 // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t). 01352 __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) 01353 : _M_refcount(__r._M_refcount, std::nothrow) 01354 { 01355 _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr; 01356 } 01357 01358 friend class __weak_ptr<_Tp, _Lp>; 01359 01360 private: 01361 01362 template<typename _Yp> 01363 using __esft_base_t = decltype(__enable_shared_from_this_base( 01364 std::declval<const __shared_count<_Lp>&>(), 01365 std::declval<_Yp*>())); 01366 01367 // Detect an accessible and unambiguous enable_shared_from_this base. 01368 template<typename _Yp, typename = void> 01369 struct __has_esft_base 01370 : false_type { }; 01371 01372 template<typename _Yp> 01373 struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>> 01374 : __not_<is_array<_Tp>> { }; // No enable shared_from_this for arrays 01375 01376 template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type> 01377 typename enable_if<__has_esft_base<_Yp2>::value>::type 01378 _M_enable_shared_from_this_with(_Yp* __p) noexcept 01379 { 01380 if (auto __base = __enable_shared_from_this_base(_M_refcount, __p)) 01381 __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount); 01382 } 01383 01384 template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type> 01385 typename enable_if<!__has_esft_base<_Yp2>::value>::type 01386 _M_enable_shared_from_this_with(_Yp*) noexcept 01387 { } 01388 01389 void* 01390 _M_get_deleter(const std::type_info& __ti) const noexcept 01391 { return _M_refcount._M_get_deleter(__ti); } 01392 01393 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 01394 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 01395 01396 template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 01397 friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept; 01398 01399 template<typename _Del, typename _Tp1> 01400 friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept; 01401 01402 element_type* _M_ptr; // Contained pointer. 01403 __shared_count<_Lp> _M_refcount; // Reference counter. 01404 }; 01405 01406 01407 // 20.7.2.2.7 shared_ptr comparisons 01408 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01409 inline bool 01410 operator==(const __shared_ptr<_Tp1, _Lp>& __a, 01411 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01412 { return __a.get() == __b.get(); } 01413 01414 template<typename _Tp, _Lock_policy _Lp> 01415 inline bool 01416 operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01417 { return !__a; } 01418 01419 template<typename _Tp, _Lock_policy _Lp> 01420 inline bool 01421 operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01422 { return !__a; } 01423 01424 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01425 inline bool 01426 operator!=(const __shared_ptr<_Tp1, _Lp>& __a, 01427 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01428 { return __a.get() != __b.get(); } 01429 01430 template<typename _Tp, _Lock_policy _Lp> 01431 inline bool 01432 operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01433 { return (bool)__a; } 01434 01435 template<typename _Tp, _Lock_policy _Lp> 01436 inline bool 01437 operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01438 { return (bool)__a; } 01439 01440 template<typename _Tp, typename _Up, _Lock_policy _Lp> 01441 inline bool 01442 operator<(const __shared_ptr<_Tp, _Lp>& __a, 01443 const __shared_ptr<_Up, _Lp>& __b) noexcept 01444 { 01445 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 01446 using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type; 01447 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; 01448 return less<_Vp>()(__a.get(), __b.get()); 01449 } 01450 01451 template<typename _Tp, _Lock_policy _Lp> 01452 inline bool 01453 operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01454 { 01455 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 01456 return less<_Tp_elt*>()(__a.get(), nullptr); 01457 } 01458 01459 template<typename _Tp, _Lock_policy _Lp> 01460 inline bool 01461 operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01462 { 01463 using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type; 01464 return less<_Tp_elt*>()(nullptr, __a.get()); 01465 } 01466 01467 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01468 inline bool 01469 operator<=(const __shared_ptr<_Tp1, _Lp>& __a, 01470 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01471 { return !(__b < __a); } 01472 01473 template<typename _Tp, _Lock_policy _Lp> 01474 inline bool 01475 operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01476 { return !(nullptr < __a); } 01477 01478 template<typename _Tp, _Lock_policy _Lp> 01479 inline bool 01480 operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01481 { return !(__a < nullptr); } 01482 01483 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01484 inline bool 01485 operator>(const __shared_ptr<_Tp1, _Lp>& __a, 01486 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01487 { return (__b < __a); } 01488 01489 template<typename _Tp, _Lock_policy _Lp> 01490 inline bool 01491 operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01492 { return nullptr < __a; } 01493 01494 template<typename _Tp, _Lock_policy _Lp> 01495 inline bool 01496 operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01497 { return __a < nullptr; } 01498 01499 template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 01500 inline bool 01501 operator>=(const __shared_ptr<_Tp1, _Lp>& __a, 01502 const __shared_ptr<_Tp2, _Lp>& __b) noexcept 01503 { return !(__a < __b); } 01504 01505 template<typename _Tp, _Lock_policy _Lp> 01506 inline bool 01507 operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 01508 { return !(__a < nullptr); } 01509 01510 template<typename _Tp, _Lock_policy _Lp> 01511 inline bool 01512 operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 01513 { return !(nullptr < __a); } 01514 01515 template<typename _Sp> 01516 struct _Sp_less : public binary_function<_Sp, _Sp, bool> 01517 { 01518 bool 01519 operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept 01520 { 01521 typedef typename _Sp::element_type element_type; 01522 return std::less<element_type*>()(__lhs.get(), __rhs.get()); 01523 } 01524 }; 01525 01526 template<typename _Tp, _Lock_policy _Lp> 01527 struct less<__shared_ptr<_Tp, _Lp>> 01528 : public _Sp_less<__shared_ptr<_Tp, _Lp>> 01529 { }; 01530 01531 // 20.7.2.2.8 shared_ptr specialized algorithms. 01532 template<typename _Tp, _Lock_policy _Lp> 01533 inline void 01534 swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept 01535 { __a.swap(__b); } 01536 01537 // 20.7.2.2.9 shared_ptr casts 01538 01539 // The seemingly equivalent code: 01540 // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) 01541 // will eventually result in undefined behaviour, attempting to 01542 // delete the same object twice. 01543 /// static_pointer_cast 01544 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 01545 inline __shared_ptr<_Tp, _Lp> 01546 static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01547 { 01548 using _Sp = __shared_ptr<_Tp, _Lp>; 01549 return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get())); 01550 } 01551 01552 // The seemingly equivalent code: 01553 // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) 01554 // will eventually result in undefined behaviour, attempting to 01555 // delete the same object twice. 01556 /// const_pointer_cast 01557 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 01558 inline __shared_ptr<_Tp, _Lp> 01559 const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01560 { 01561 using _Sp = __shared_ptr<_Tp, _Lp>; 01562 return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get())); 01563 } 01564 01565 // The seemingly equivalent code: 01566 // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) 01567 // will eventually result in undefined behaviour, attempting to 01568 // delete the same object twice. 01569 /// dynamic_pointer_cast 01570 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 01571 inline __shared_ptr<_Tp, _Lp> 01572 dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01573 { 01574 using _Sp = __shared_ptr<_Tp, _Lp>; 01575 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get())) 01576 return _Sp(__r, __p); 01577 return _Sp(); 01578 } 01579 01580 #if __cplusplus > 201402L 01581 template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 01582 inline __shared_ptr<_Tp, _Lp> 01583 reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 01584 { 01585 using _Sp = __shared_ptr<_Tp, _Lp>; 01586 return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get())); 01587 } 01588 #endif 01589 01590 template<typename _Tp, _Lock_policy _Lp> 01591 class __weak_ptr 01592 { 01593 template<typename _Yp, typename _Res = void> 01594 using _Compatible = typename 01595 enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type; 01596 01597 // Constraint for assignment from shared_ptr and weak_ptr: 01598 template<typename _Yp> 01599 using _Assignable = _Compatible<_Yp, __weak_ptr&>; 01600 01601 public: 01602 using element_type = typename remove_extent<_Tp>::type; 01603 01604 constexpr __weak_ptr() noexcept 01605 : _M_ptr(nullptr), _M_refcount() 01606 { } 01607 01608 __weak_ptr(const __weak_ptr&) noexcept = default; 01609 01610 ~__weak_ptr() = default; 01611 01612 // The "obvious" converting constructor implementation: 01613 // 01614 // template<typename _Tp1> 01615 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 01616 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 01617 // { } 01618 // 01619 // has a serious problem. 01620 // 01621 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 01622 // conversion may require access to *__r._M_ptr (virtual inheritance). 01623 // 01624 // It is not possible to avoid spurious access violations since 01625 // in multithreaded programs __r._M_ptr may be invalidated at any point. 01626 template<typename _Yp, typename = _Compatible<_Yp>> 01627 __weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept 01628 : _M_refcount(__r._M_refcount) 01629 { _M_ptr = __r.lock().get(); } 01630 01631 template<typename _Yp, typename = _Compatible<_Yp>> 01632 __weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept 01633 : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 01634 { } 01635 01636 __weak_ptr(__weak_ptr&& __r) noexcept 01637 : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount)) 01638 { __r._M_ptr = nullptr; } 01639 01640 template<typename _Yp, typename = _Compatible<_Yp>> 01641 __weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept 01642 : _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount)) 01643 { __r._M_ptr = nullptr; } 01644 01645 __weak_ptr& 01646 operator=(const __weak_ptr& __r) noexcept = default; 01647 01648 template<typename _Yp> 01649 _Assignable<_Yp> 01650 operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept 01651 { 01652 _M_ptr = __r.lock().get(); 01653 _M_refcount = __r._M_refcount; 01654 return *this; 01655 } 01656 01657 template<typename _Yp> 01658 _Assignable<_Yp> 01659 operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept 01660 { 01661 _M_ptr = __r._M_ptr; 01662 _M_refcount = __r._M_refcount; 01663 return *this; 01664 } 01665 01666 __weak_ptr& 01667 operator=(__weak_ptr&& __r) noexcept 01668 { 01669 _M_ptr = __r._M_ptr; 01670 _M_refcount = std::move(__r._M_refcount); 01671 __r._M_ptr = nullptr; 01672 return *this; 01673 } 01674 01675 template<typename _Yp> 01676 _Assignable<_Yp> 01677 operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept 01678 { 01679 _M_ptr = __r.lock().get(); 01680 _M_refcount = std::move(__r._M_refcount); 01681 __r._M_ptr = nullptr; 01682 return *this; 01683 } 01684 01685 __shared_ptr<_Tp, _Lp> 01686 lock() const noexcept 01687 { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); } 01688 01689 long 01690 use_count() const noexcept 01691 { return _M_refcount._M_get_use_count(); } 01692 01693 bool 01694 expired() const noexcept 01695 { return _M_refcount._M_get_use_count() == 0; } 01696 01697 template<typename _Tp1> 01698 bool 01699 owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept 01700 { return _M_refcount._M_less(__rhs._M_refcount); } 01701 01702 template<typename _Tp1> 01703 bool 01704 owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept 01705 { return _M_refcount._M_less(__rhs._M_refcount); } 01706 01707 void 01708 reset() noexcept 01709 { __weak_ptr().swap(*this); } 01710 01711 void 01712 swap(__weak_ptr& __s) noexcept 01713 { 01714 std::swap(_M_ptr, __s._M_ptr); 01715 _M_refcount._M_swap(__s._M_refcount); 01716 } 01717 01718 private: 01719 // Used by __enable_shared_from_this. 01720 void 01721 _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept 01722 { 01723 if (use_count() == 0) 01724 { 01725 _M_ptr = __ptr; 01726 _M_refcount = __refcount; 01727 } 01728 } 01729 01730 template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 01731 template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 01732 friend class __enable_shared_from_this<_Tp, _Lp>; 01733 friend class enable_shared_from_this<_Tp>; 01734 01735 element_type* _M_ptr; // Contained pointer. 01736 __weak_count<_Lp> _M_refcount; // Reference counter. 01737 }; 01738 01739 // 20.7.2.3.6 weak_ptr specialized algorithms. 01740 template<typename _Tp, _Lock_policy _Lp> 01741 inline void 01742 swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept 01743 { __a.swap(__b); } 01744 01745 template<typename _Tp, typename _Tp1> 01746 struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool> 01747 { 01748 bool 01749 operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept 01750 { return __lhs.owner_before(__rhs); } 01751 01752 bool 01753 operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept 01754 { return __lhs.owner_before(__rhs); } 01755 01756 bool 01757 operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept 01758 { return __lhs.owner_before(__rhs); } 01759 }; 01760 01761 template<> 01762 struct _Sp_owner_less<void, void> 01763 { 01764 template<typename _Tp, typename _Up> 01765 auto 01766 operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept 01767 -> decltype(__lhs.owner_before(__rhs)) 01768 { return __lhs.owner_before(__rhs); } 01769 01770 using is_transparent = void; 01771 }; 01772 01773 template<typename _Tp, _Lock_policy _Lp> 01774 struct owner_less<__shared_ptr<_Tp, _Lp>> 01775 : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>> 01776 { }; 01777 01778 template<typename _Tp, _Lock_policy _Lp> 01779 struct owner_less<__weak_ptr<_Tp, _Lp>> 01780 : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>> 01781 { }; 01782 01783 01784 template<typename _Tp, _Lock_policy _Lp> 01785 class __enable_shared_from_this 01786 { 01787 protected: 01788 constexpr __enable_shared_from_this() noexcept { } 01789 01790 __enable_shared_from_this(const __enable_shared_from_this&) noexcept { } 01791 01792 __enable_shared_from_this& 01793 operator=(const __enable_shared_from_this&) noexcept 01794 { return *this; } 01795 01796 ~__enable_shared_from_this() { } 01797 01798 public: 01799 __shared_ptr<_Tp, _Lp> 01800 shared_from_this() 01801 { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 01802 01803 __shared_ptr<const _Tp, _Lp> 01804 shared_from_this() const 01805 { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } 01806 01807 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 01808 __weak_ptr<_Tp, _Lp> 01809 weak_from_this() noexcept 01810 { return this->_M_weak_this; } 01811 01812 __weak_ptr<const _Tp, _Lp> 01813 weak_from_this() const noexcept 01814 { return this->_M_weak_this; } 01815 #endif 01816 01817 private: 01818 template<typename _Tp1> 01819 void 01820 _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept 01821 { _M_weak_this._M_assign(__p, __n); } 01822 01823 friend const __enable_shared_from_this* 01824 __enable_shared_from_this_base(const __shared_count<_Lp>&, 01825 const __enable_shared_from_this* __p) 01826 { return __p; } 01827 01828 template<typename, _Lock_policy> 01829 friend class __shared_ptr; 01830 01831 mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 01832 }; 01833 01834 template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args> 01835 inline __shared_ptr<_Tp, _Lp> 01836 __allocate_shared(const _Alloc& __a, _Args&&... __args) 01837 { 01838 return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a}, 01839 std::forward<_Args>(__args)...); 01840 } 01841 01842 template<typename _Tp, _Lock_policy _Lp, typename... _Args> 01843 inline __shared_ptr<_Tp, _Lp> 01844 __make_shared(_Args&&... __args) 01845 { 01846 typedef typename std::remove_const<_Tp>::type _Tp_nc; 01847 return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(), 01848 std::forward<_Args>(__args)...); 01849 } 01850 01851 /// std::hash specialization for __shared_ptr. 01852 template<typename _Tp, _Lock_policy _Lp> 01853 struct hash<__shared_ptr<_Tp, _Lp>> 01854 : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>> 01855 { 01856 size_t 01857 operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept 01858 { 01859 return hash<typename __shared_ptr<_Tp, _Lp>::element_type*>()( 01860 __s.get()); 01861 } 01862 }; 01863 01864 _GLIBCXX_END_NAMESPACE_VERSION 01865 } // namespace 01866 01867 #endif // _SHARED_PTR_BASE_H