111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// shared_ptr and weak_ptr implementation details -*- C++ -*- 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (C) 2007-2014 Free Software Foundation, Inc. 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file is part of the GNU ISO C++ Library. This library is free 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// software; you can redistribute it and/or modify it under the 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// terms of the GNU General Public License as published by the 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Free Software Foundation; either version 3, or (at your option) 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// any later version. 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This library is distributed in the hope that it will be useful, 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// but WITHOUT ANY WARRANTY; without even the implied warranty of 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// GNU General Public License for more details. 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Under Section 7 of GPL version 3, you are granted additional 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// permissions described in the GCC Runtime Library Exception, version 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 3.1, as published by the Free Software Foundation. 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// You should have received a copy of the GNU General Public License and 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// a copy of the GCC Runtime Library Exception along with this program; 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// <http://www.gnu.org/licenses/>. 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// GCC Note: Based on files from version 1.32.0 of the Boost library. 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// shared_count.hpp 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// shared_ptr.hpp 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (C) 2001, 2002, 2003 Peter Dimov 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// weak_ptr.hpp 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (C) 2001, 2002, 2003 Peter Dimov 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// enable_shared_from_this.hpp 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (C) 2002 Peter Dimov 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Distributed under the Boost Software License, Version 1.0. (See 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// accompanying file LICENSE_1_0.txt or copy at 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// http://www.boost.org/LICENSE_1_0.txt) 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/** @file bits/shared_ptr_base.h 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This is an internal header file, included by other library headers. 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Do not attempt to use it directly. @headername{memory} 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _SHARED_PTR_BASE_H 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _SHARED_PTR_BASE_H 1 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <ext/aligned_buffer.h> 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace std _GLIBCXX_VISIBILITY(default) 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_GLIBCXX_BEGIN_NAMESPACE_VERSION 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if _GLIBCXX_USE_DEPRECATED 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename> class auto_ptr; 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /** 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * @brief Exception possibly thrown by @c shared_ptr. 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * @ingroup exceptions 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class bad_weak_ptr : public std::exception 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual char const* 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert what() const noexcept; 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual ~bad_weak_ptr() noexcept; 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Substitute for bad_weak_ptr object in the case of -fno-exceptions. 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __throw_bad_weak_ptr() 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); } 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using __gnu_cxx::_Lock_policy; 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using __gnu_cxx::__default_lock_policy; 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using __gnu_cxx::_S_single; 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using __gnu_cxx::_S_mutex; 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using __gnu_cxx::_S_atomic; 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Empty helper class except when the template argument is _S_mutex. 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<_Lock_policy _Lp> 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Mutex_base 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert protected: 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // The atomic policy uses fully-fenced builtins, single doesn't care. 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert enum { _S_need_barriers = 0 }; 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Mutex_base<_S_mutex> 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : public __gnu_cxx::__mutex 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert protected: 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // This policy is used when atomic builtins are not available. 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // The replacement atomic operations might not have the necessary 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // memory barriers. 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert enum { _S_need_barriers = 1 }; 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<_Lock_policy _Lp = __default_lock_policy> 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Sp_counted_base 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : public _Mutex_base<_Lp> 10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base() noexcept 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_use_count(1), _M_weak_count(1) { } 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual 11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~_Sp_counted_base() noexcept 11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Called when _M_use_count drops to zero, to release the resources 11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // managed by *this. 12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void 12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_dispose() noexcept = 0; 12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Called when _M_weak_count drops to zero. 12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void 12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_destroy() noexcept 12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { delete this; } 12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void* 12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_deleter(const std::type_info&) noexcept = 0; 13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_add_ref_copy() 13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } 13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_add_ref_lock(); 13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_add_ref_lock_nothrow(); 14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_release() noexcept 14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Be race-detector-friendly. For more info see bits/c++config. 14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count); 14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1) 14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count); 14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_dispose(); 15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // There must be a memory barrier between dispose() and destroy() 15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // to ensure that the effects of dispose() are observed in the 15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // thread that runs destroy(). 15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html 15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_Mutex_base<_Lp>::_S_need_barriers) 15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_READ_MEM_BARRIER; 15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_WRITE_MEM_BARRIER; 15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Be race-detector-friendly. For more info see bits/c++config. 16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, 16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert -1) == 1) 16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_destroy(); 16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_weak_add_ref() noexcept 17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } 17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_weak_release() noexcept 17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Be race-detector-friendly. For more info see bits/c++config. 17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count); 18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) 18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count); 18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_Mutex_base<_Lp>::_S_need_barriers) 18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // See _M_release(), 18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // destroy() must observe results of dispose() 18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_READ_MEM_BARRIER; 18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_WRITE_MEM_BARRIER; 18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_destroy(); 19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert long 19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_use_count() const noexcept 19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // No memory barrier is used here so there is no synchronization 19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // with other threads. 19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED); 20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base(_Sp_counted_base const&) = delete; 20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base& operator=(_Sp_counted_base const&) = delete; 20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Atomic_word _M_use_count; // #shared 20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Atomic_word _M_weak_count; // #weak + (#shared != 0) 20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_S_single>:: 21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_add_ref_lock() 21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_use_count == 0) 21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __throw_bad_weak_ptr(); 21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ++_M_use_count; 21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_S_mutex>:: 22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_add_ref_lock() 22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __gnu_cxx::__scoped_lock sentry(*this); 22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_use_count = 0; 22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __throw_bad_weak_ptr(); 23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_S_atomic>:: 23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_add_ref_lock() 23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Perform lock-free add-if-not-zero operation. 23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Atomic_word __count = _M_get_use_count(); 24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert do 24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__count == 0) 24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __throw_bad_weak_ptr(); 24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Replace the current counter value with the old value + 1, as 24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // long as it's not changed meanwhile. 24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, 24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert true, __ATOMIC_ACQ_REL, 24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __ATOMIC_RELAXED)); 25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_S_single>:: 25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_add_ref_lock_nothrow() 25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_use_count == 0) 25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ++_M_use_count; 26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return true; 26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_S_mutex>:: 26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_add_ref_lock_nothrow() 26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __gnu_cxx::__scoped_lock sentry(*this); 26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_use_count = 0; 27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return true; 27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_S_atomic>:: 28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_add_ref_lock_nothrow() 28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Perform lock-free add-if-not-zero operation. 28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Atomic_word __count = _M_get_use_count(); 28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert do 28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__count == 0) 28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Replace the current counter value with the old value + 1, as 28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // long as it's not changed meanwhile. 29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, 29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert true, __ATOMIC_ACQ_REL, 29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __ATOMIC_RELAXED)); 29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return true; 29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_S_single>::_M_add_ref_copy() 30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { ++_M_use_count; } 30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_S_single>::_M_release() noexcept 30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (--_M_use_count == 0) 30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_dispose(); 30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (--_M_weak_count == 0) 31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_destroy(); 31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept 31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { ++_M_weak_count; } 31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_S_single>::_M_weak_release() noexcept 32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (--_M_weak_count == 0) 32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_destroy(); 32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline long 32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept 33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_use_count; } 33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Forward declarations. 33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class __shared_ptr; 33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class __weak_ptr; 33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class __enable_shared_from_this; 34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class shared_ptr; 34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class weak_ptr; 34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct owner_less; 35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class enable_shared_from_this; 35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<_Lock_policy _Lp = __default_lock_policy> 35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class __weak_count; 35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<_Lock_policy _Lp = __default_lock_policy> 35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class __shared_count; 36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Counted ptr with no deleter or allocator support 36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Ptr, _Lock_policy _Lp> 36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Sp_counted_ptr final : public _Sp_counted_base<_Lp> 36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit 36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_ptr(_Ptr __p) noexcept 36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(__p) { } 37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void 37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_dispose() noexcept 37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { delete _M_ptr; } 37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void 37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_destroy() noexcept 37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { delete this; } 37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void* 38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_deleter(const std::type_info&) noexcept 38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return nullptr; } 38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_ptr(const _Sp_counted_ptr&) = delete; 38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete; 38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Ptr _M_ptr; 38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { } 39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { } 39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { } 40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<int _Nm, typename _Tp, 40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)> 40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Sp_ebo_helper; 40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// Specialization using EBO. 40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<int _Nm, typename _Tp> 40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp 40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { } 41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _Tp& 41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); } 41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// Specialization not using EBO. 41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<int _Nm, typename _Tp> 41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Sp_ebo_helper<_Nm, _Tp, false> 41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { } 42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _Tp& 42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_get(_Sp_ebo_helper& __eboh) 42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __eboh._M_tp; } 42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Tp _M_tp; 42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Support for custom deleter and/or allocator 43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp> 43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Sp_counted_deleter final : public _Sp_counted_base<_Lp> 43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc> 43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Sp_ebo_helper<0, _Deleter> _Del_base; 43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base; 43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept 44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(__p), _Del_base(__d), _Alloc_base(__a) 44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); } 44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); } 44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Ptr _M_ptr; 44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // __d(__p) must not throw. 45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept 45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_impl(__p, __d, _Alloc()) { } 45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // __d(__p) must not throw. 45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept 45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_impl(__p, __d, __a) { } 45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~_Sp_counted_deleter() noexcept { } 46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void 46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_dispose() noexcept 46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _M_impl._M_del()(_M_impl._M_ptr); } 46411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 46511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void 46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_destroy() noexcept 46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename allocator_traits<_Alloc>::template 46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert rebind_traits<_Sp_counted_deleter> _Alloc_traits; 47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename _Alloc_traits::allocator_type __a(_M_impl._M_alloc()); 47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc_traits::destroy(__a, this); 47211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc_traits::deallocate(__a, this, 1); 47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 47411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void* 47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_deleter(const std::type_info& __ti) noexcept 47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef __GXX_RTTI 47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __ti == typeid(_Deleter) ? &_M_impl._M_del() : nullptr; 48011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else 48111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return nullptr; 48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 48311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 48511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Impl _M_impl; 48711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 48811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // helpers for make_shared / allocate_shared 49011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Sp_make_shared_tag { }; 49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 49311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, typename _Alloc, _Lock_policy _Lp> 49411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp> 49511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 49611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class _Impl : _Sp_ebo_helper<0, _Alloc> 49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Sp_ebo_helper<0, _Alloc> _A_base; 49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 50011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 50111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { } 50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); } 50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __gnu_cxx::__aligned_buffer<_Tp> _M_storage; 50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename... _Args> 51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args) 51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_impl(__a) 51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // _GLIBCXX_RESOLVE_LIB_DEFECTS 51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 2070. allocate_shared should use allocator_traits<A>::construct 51511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert allocator_traits<_Alloc>::construct(__a, _M_ptr(), 51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::forward<_Args>(__args)...); // might throw 51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~_Sp_counted_ptr_inplace() noexcept { } 52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void 52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_dispose() noexcept 52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr()); 52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 52611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 52711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Override because the allocator needs to know the dynamic type 52811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void 52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_destroy() noexcept 53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename allocator_traits<_Alloc>::template 53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert rebind_traits<_Sp_counted_ptr_inplace> _Alloc_traits; 53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename _Alloc_traits::allocator_type __a(_M_impl._M_alloc()); 53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc_traits::destroy(__a, this); 53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc_traits::deallocate(__a, this, 1); 53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Sneaky trick so __shared_ptr can get the managed pointer 53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert virtual void* 54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_deleter(const std::type_info& __ti) noexcept 54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef __GXX_RTTI 54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__ti == typeid(_Sp_make_shared_tag)) 54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return const_cast<typename remove_cv<_Tp>::type*>(_M_ptr()); 54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return nullptr; 54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 54811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 54911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); } 55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Impl _M_impl; 55311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 55611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<_Lock_policy _Lp> 55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class __shared_count 55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert constexpr __shared_count() noexcept : _M_pi(0) 56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Ptr> 56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit 56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count(_Ptr __p) : _M_pi(0) 56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __try 56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); 57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __catch(...) 57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert delete __p; 57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __throw_exception_again; 57511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 57711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Ptr, typename _Deleter> 57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count(_Ptr __p, _Deleter __d) 58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : __shared_count(__p, std::move(__d), allocator<void>()) 58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Ptr, typename _Deleter, typename _Alloc> 58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0) 58511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type; 58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename allocator_traits<_Alloc>::template 58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert rebind_traits<_Sp_cd_type> _Alloc_traits; 58911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename _Alloc_traits::allocator_type __a2(__a); 59011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_cd_type* __mem = 0; 59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __try 59211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __mem = _Alloc_traits::allocate(__a2, 1); 59411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc_traits::construct(__a2, __mem, 59511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __p, std::move(__d), std::move(__a)); 59611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi = __mem; 59711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 59811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __catch(...) 59911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 60011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __d(__p); // Call _Deleter on __p. 60111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__mem) 60211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc_traits::deallocate(__a2, __mem, 1); 60311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __throw_exception_again; 60411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 60511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 60611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 60711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, typename _Alloc, typename... _Args> 60811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a, 60911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Args&&... __args) 61011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_pi(0) 61111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 61211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type; 61311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename allocator_traits<_Alloc>::template 61411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert rebind_traits<_Sp_cp_type> _Alloc_traits; 61511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename _Alloc_traits::allocator_type __a2(__a); 61611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_cp_type* __mem = _Alloc_traits::allocate(__a2, 1); 61711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __try 61811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 61911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc_traits::construct(__a2, __mem, std::move(__a), 62011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::forward<_Args>(__args)...); 62111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi = __mem; 62211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 62311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __catch(...) 62411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 62511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc_traits::deallocate(__a2, __mem, 1); 62611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __throw_exception_again; 62711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 62811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 62911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 63011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if _GLIBCXX_USE_DEPRECATED 63111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Special case for auto_ptr<_Tp> to provide the strong guarantee. 63211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp> 63311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit 63411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count(std::auto_ptr<_Tp>&& __r); 63511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 63611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 63711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee. 63811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, typename _Del> 63911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit 64011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0) 64111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 64211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using _Ptr = typename unique_ptr<_Tp, _Del>::pointer; 64311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using _Del2 = typename conditional<is_reference<_Del>::value, 64411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reference_wrapper<typename remove_reference<_Del>::type>, 64511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Del>::type; 64611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using _Sp_cd_type 64711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>; 64811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using _Alloc = allocator<_Sp_cd_type>; 64911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert using _Alloc_traits = allocator_traits<_Alloc>; 65011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc __a; 65111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1); 65211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc_traits::construct(__a, __mem, __r.release(), 65311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r.get_deleter()); // non-throwing 65411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi = __mem; 65511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 65611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 65711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 65811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit __shared_count(const __weak_count<_Lp>& __r); 65911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 66011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Does not throw if __r._M_get_use_count() == 0, caller must check. 66111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t); 66211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 66311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~__shared_count() noexcept 66411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 66511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_pi != nullptr) 66611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi->_M_release(); 66711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 66811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 66911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count(const __shared_count& __r) noexcept 67011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_pi(__r._M_pi) 67111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 67211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_pi != 0) 67311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi->_M_add_ref_copy(); 67411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 67511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 67611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count& 67711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(const __shared_count& __r) noexcept 67811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 67911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 68011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__tmp != _M_pi) 68111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 68211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__tmp != 0) 68311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __tmp->_M_add_ref_copy(); 68411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_pi != 0) 68511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi->_M_release(); 68611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi = __tmp; 68711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 68811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 68911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 69011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 69111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 69211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_swap(__shared_count& __r) noexcept 69311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 69411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 69511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r._M_pi = _M_pi; 69611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi = __tmp; 69711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 69811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 69911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert long 70011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_use_count() const noexcept 70111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 70211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 70311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 70411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_unique() const noexcept 70511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return this->_M_get_use_count() == 1; } 70611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 70711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void* 70811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_deleter(const std::type_info& __ti) const noexcept 70911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; } 71011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 71111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 71211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_less(const __shared_count& __rhs) const noexcept 71311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 71411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 71511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 71611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_less(const __weak_count<_Lp>& __rhs) const noexcept 71711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 71811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 71911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Friend function injected into enclosing namespace and found by ADL 72011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert friend inline bool 72111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator==(const __shared_count& __a, const __shared_count& __b) noexcept 72211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __a._M_pi == __b._M_pi; } 72311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 72411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 72511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert friend class __weak_count<_Lp>; 72611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 72711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_Lp>* _M_pi; 72811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 72911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 73011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 73111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<_Lock_policy _Lp> 73211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class __weak_count 73311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 73411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 73511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert constexpr __weak_count() noexcept : _M_pi(0) 73611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 73711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 73811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __weak_count(const __shared_count<_Lp>& __r) noexcept 73911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_pi(__r._M_pi) 74011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 74111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_pi != 0) 74211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi->_M_weak_add_ref(); 74311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 74411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 74511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __weak_count(const __weak_count<_Lp>& __r) noexcept 74611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_pi(__r._M_pi) 74711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 74811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_pi != 0) 74911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi->_M_weak_add_ref(); 75011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 75111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 75211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~__weak_count() noexcept 75311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 75411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_pi != 0) 75511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi->_M_weak_release(); 75611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 75711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 75811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __weak_count<_Lp>& 75911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(const __shared_count<_Lp>& __r) noexcept 76011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 76111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 76211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__tmp != 0) 76311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __tmp->_M_weak_add_ref(); 76411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_pi != 0) 76511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi->_M_weak_release(); 76611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi = __tmp; 76711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 76811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 76911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 77011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __weak_count<_Lp>& 77111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(const __weak_count<_Lp>& __r) noexcept 77211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 77311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 77411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__tmp != 0) 77511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __tmp->_M_weak_add_ref(); 77611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_pi != 0) 77711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi->_M_weak_release(); 77811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi = __tmp; 77911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 78011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 78111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 78211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 78311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_swap(__weak_count<_Lp>& __r) noexcept 78411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 78511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 78611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r._M_pi = _M_pi; 78711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi = __tmp; 78811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 78911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 79011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert long 79111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_use_count() const noexcept 79211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 79311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 79411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 79511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_less(const __weak_count& __rhs) const noexcept 79611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 79711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 79811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 79911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_less(const __shared_count<_Lp>& __rhs) const noexcept 80011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } 80111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 80211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Friend function injected into enclosing namespace and found by ADL 80311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert friend inline bool 80411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator==(const __weak_count& __a, const __weak_count& __b) noexcept 80511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __a._M_pi == __b._M_pi; } 80611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 80711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 80811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert friend class __shared_count<_Lp>; 80911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 81011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Sp_counted_base<_Lp>* _M_pi; 81111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 81211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 81311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Now that __weak_count is defined we can define this constructor: 81411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<_Lock_policy _Lp> 81511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline 81611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r) 81711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_pi(__r._M_pi) 81811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 81911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_pi != nullptr) 82011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi->_M_add_ref_lock(); 82111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else 82211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __throw_bad_weak_ptr(); 82311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 82411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 82511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Now that __weak_count is defined we can define this constructor: 82611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<_Lock_policy _Lp> 82711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline 82811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count<_Lp>:: 82911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) 83011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_pi(__r._M_pi) 83111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 83211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_pi != nullptr) 83311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_pi->_M_add_ref_lock_nothrow()) 83411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_pi = nullptr; 83511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 83611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 83711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Support for enable_shared_from_this. 83811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 83911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Friend of __enable_shared_from_this. 84011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> 84111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 84211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this_helper(const __shared_count<_Lp>&, 84311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const __enable_shared_from_this<_Tp1, 84411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Lp>*, const _Tp2*) noexcept; 84511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 84611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Friend of enable_shared_from_this. 84711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Tp2> 84811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 84911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this_helper(const __shared_count<>&, 85011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const enable_shared_from_this<_Tp1>*, 85111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Tp2*) noexcept; 85211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 85311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<_Lock_policy _Lp> 85411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 85511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) noexcept 85611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 85711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 85811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 85911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 86011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class __shared_ptr 86111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 86211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 86311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Tp element_type; 86411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 86511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert constexpr __shared_ptr() noexcept 86611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(0), _M_refcount() 86711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 86811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 86911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 87011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit __shared_ptr(_Tp1* __p) 87111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(__p), _M_refcount(__p) 87211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 87311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 87411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert( !is_void<_Tp1>::value, "incomplete type" ); 87511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_assert( sizeof(_Tp1) > 0, "incomplete type" ); 87611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this_helper(_M_refcount, __p, __p); 87711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 87811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 87911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Deleter> 88011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(_Tp1* __p, _Deleter __d) 88111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(__p), _M_refcount(__p, __d) 88211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 88311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 88411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 88511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this_helper(_M_refcount, __p, __p); 88611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 88711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 88811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Deleter, typename _Alloc> 88911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) 89011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(__p), _M_refcount(__p, __d, std::move(__a)) 89111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 89211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 89311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 89411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this_helper(_M_refcount, __p, __p); 89511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 89611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 89711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Deleter> 89811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(nullptr_t __p, _Deleter __d) 89911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(0), _M_refcount(__p, __d) 90011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 90111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 90211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Deleter, typename _Alloc> 90311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 90411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(0), _M_refcount(__p, __d, std::move(__a)) 90511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 90611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 90711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 90811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept 90911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws 91011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 91111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 91211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(const __shared_ptr&) noexcept = default; 91311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr& operator=(const __shared_ptr&) noexcept = default; 91411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~__shared_ptr() = default; 91511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 91611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename = typename 91711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 91811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 91911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 92011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 92111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 92211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(__shared_ptr&& __r) noexcept 92311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(__r._M_ptr), _M_refcount() 92411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 92511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount._M_swap(__r._M_refcount); 92611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r._M_ptr = 0; 92711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 92811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 92911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename = typename 93011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 93111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept 93211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(__r._M_ptr), _M_refcount() 93311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 93411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount._M_swap(__r._M_refcount); 93511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r._M_ptr = 0; 93611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 93711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 93811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 93911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 94011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_refcount(__r._M_refcount) // may throw 94111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 94211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 94311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 94411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // It is now safe to copy __r._M_ptr, as 94511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // _M_refcount(__r._M_refcount) did not throw. 94611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ptr = __r._M_ptr; 94711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 94811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 94911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // If an exception is thrown this constructor has no effect. 95011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Del> 95111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r) 95211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(__r.get()), _M_refcount() 95311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 95411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 95511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert auto __raw = _S_raw_ptr(__r.get()); 95611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount = __shared_count<_Lp>(std::move(__r)); 95711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this_helper(_M_refcount, __raw, __raw); 95811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 95911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 96011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if _GLIBCXX_USE_DEPRECATED 96111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Postcondition: use_count() == 1 and __r.get() == 0 96211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 96311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(std::auto_ptr<_Tp1>&& __r); 96411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 96511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 96611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /* TODO: use delegating constructor */ 96711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert constexpr __shared_ptr(nullptr_t) noexcept 96811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(0), _M_refcount() 96911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 97011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 97111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 97211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr& 97311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 97411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 97511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ptr = __r._M_ptr; 97611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 97711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 97811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 97911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 98011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if _GLIBCXX_USE_DEPRECATED 98111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 98211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr& 98311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(std::auto_ptr<_Tp1>&& __r) 98411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 98511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(std::move(__r)).swap(*this); 98611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 98711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 98811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 98911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 99011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr& 99111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(__shared_ptr&& __r) noexcept 99211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 99311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(std::move(__r)).swap(*this); 99411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 99511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 99611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 99711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<class _Tp1> 99811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr& 99911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(__shared_ptr<_Tp1, _Lp>&& __r) noexcept 100011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 100111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(std::move(__r)).swap(*this); 100211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 100311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 100411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 100511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Del> 100611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr& 100711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(std::unique_ptr<_Tp1, _Del>&& __r) 100811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 100911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(std::move(__r)).swap(*this); 101011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 101111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 101211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 101311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 101411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reset() noexcept 101511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { __shared_ptr().swap(*this); } 101611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 101711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 101811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 101911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reset(_Tp1* __p) // _Tp1 must be complete. 102011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 102111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Catch self-reset errors. 102211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 102311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(__p).swap(*this); 102411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 102511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 102611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Deleter> 102711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 102811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reset(_Tp1* __p, _Deleter __d) 102911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { __shared_ptr(__p, __d).swap(*this); } 103011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 103111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Deleter, typename _Alloc> 103211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 103311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reset(_Tp1* __p, _Deleter __d, _Alloc __a) 103411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { __shared_ptr(__p, __d, std::move(__a)).swap(*this); } 103511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 103611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Allow class instantiation when _Tp is [cv-qual] void. 103711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename std::add_lvalue_reference<_Tp>::type 103811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator*() const noexcept 103911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 104011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 104111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *_M_ptr; 104211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 104311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 104411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Tp* 104511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator->() const noexcept 104611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 104711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 104811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _M_ptr; 104911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 105011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 105111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Tp* 105211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert get() const noexcept 105311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_ptr; } 105411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 105511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert explicit operator bool() const // never throws 105611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_ptr == 0 ? false : true; } 105711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 105811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 105911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert unique() const noexcept 106011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_refcount._M_unique(); } 106111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 106211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert long 106311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert use_count() const noexcept 106411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_refcount._M_get_use_count(); } 106511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 106611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 106711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert swap(__shared_ptr<_Tp, _Lp>& __other) noexcept 106811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 106911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::swap(_M_ptr, __other._M_ptr); 107011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount._M_swap(__other._M_refcount); 107111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 107211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 107311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 107411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 107511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const 107611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_refcount._M_less(__rhs._M_refcount); } 107711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 107811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 107911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 108011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const 108111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_refcount._M_less(__rhs._M_refcount); } 108211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 108311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef __GXX_RTTI 108411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert protected: 108511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // This constructor is non-standard, it is used by allocate_shared. 108611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Alloc, typename... _Args> 108711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 108811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Args&&... __args) 108911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a, 109011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::forward<_Args>(__args)...) 109111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 109211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // _M_ptr needs to point to the newly constructed object. 109311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // This relies on _Sp_counted_ptr_inplace::_M_get_deleter. 109411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void* __p = _M_refcount._M_get_deleter(typeid(__tag)); 109511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ptr = static_cast<_Tp*>(__p); 109611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr); 109711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 109811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else 109911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Alloc> 110011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Deleter 110111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 110211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void operator()(_Tp* __ptr) 110311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 110411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef allocator_traits<_Alloc> _Alloc_traits; 110511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc_traits::destroy(_M_alloc, __ptr); 110611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc_traits::deallocate(_M_alloc, __ptr, 1); 110711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 110811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Alloc _M_alloc; 110911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 111011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 111111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Alloc, typename... _Args> 111211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 111311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Args&&... __args) 111411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(), _M_refcount() 111511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 111611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename _Alloc::template rebind<_Tp>::other _Alloc2; 111711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Deleter<_Alloc2> __del = { _Alloc2(__a) }; 111811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef allocator_traits<_Alloc2> __traits; 111911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ptr = __traits::allocate(__del._M_alloc, 1); 112011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __try 112111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 112211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // _GLIBCXX_RESOLVE_LIB_DEFECTS 112311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 2070. allocate_shared should use allocator_traits<A>::construct 112411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __traits::construct(__del._M_alloc, _M_ptr, 112511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::forward<_Args>(__args)...); 112611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 112711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __catch(...) 112811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 112911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __traits::deallocate(__del._M_alloc, _M_ptr, 1); 113011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __throw_exception_again; 113111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 113211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc); 113311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount._M_swap(__count); 113411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr); 113511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 113611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 113711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 113811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc, 113911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename... _Args> 114011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert friend __shared_ptr<_Tp1, _Lp1> 114111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __allocate_shared(const _Alloc& __a, _Args&&... __args); 114211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 114311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // This constructor is used by __weak_ptr::lock() and 114411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t). 114511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) 114611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_refcount(__r._M_refcount, std::nothrow) 114711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 114811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr; 114911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 115011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 115111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert friend class __weak_ptr<_Tp, _Lp>; 115211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 115311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 115411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void* 115511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_deleter(const std::type_info& __ti) const noexcept 115611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_refcount._M_get_deleter(__ti); } 115711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 115811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 115911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _Tp1* 116011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_raw_ptr(_Tp1* __ptr) 116111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __ptr; } 116211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 116311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 116411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static auto 116511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_raw_ptr(_Tp1 __ptr) -> decltype(std::__addressof(*__ptr)) 116611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return std::__addressof(*__ptr); } 116711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 116811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 116911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 117011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 117111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 117211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept; 117311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 117411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Tp* _M_ptr; // Contained pointer. 117511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_count<_Lp> _M_refcount; // Reference counter. 117611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 117711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 117811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 117911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 20.7.2.2.7 shared_ptr comparisons 118011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 118111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 118211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator==(const __shared_ptr<_Tp1, _Lp>& __a, 118311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const __shared_ptr<_Tp2, _Lp>& __b) noexcept 118411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __a.get() == __b.get(); } 118511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 118611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 118711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 118811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 118911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return !__a; } 119011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 119111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 119211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 119311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 119411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return !__a; } 119511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 119611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 119711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 119811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator!=(const __shared_ptr<_Tp1, _Lp>& __a, 119911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const __shared_ptr<_Tp2, _Lp>& __b) noexcept 120011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __a.get() != __b.get(); } 120111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 120211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 120311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 120411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 120511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (bool)__a; } 120611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 120711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 120811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 120911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 121011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (bool)__a; } 121111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 121211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 121311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 121411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator<(const __shared_ptr<_Tp1, _Lp>& __a, 121511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const __shared_ptr<_Tp2, _Lp>& __b) noexcept 121611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 121711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT; 121811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return std::less<_CT>()(__a.get(), __b.get()); 121911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 122011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 122111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 122211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 122311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 122411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return std::less<_Tp*>()(__a.get(), nullptr); } 122511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 122611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 122711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 122811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 122911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return std::less<_Tp*>()(nullptr, __a.get()); } 123011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 123111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 123211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 123311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator<=(const __shared_ptr<_Tp1, _Lp>& __a, 123411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const __shared_ptr<_Tp2, _Lp>& __b) noexcept 123511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return !(__b < __a); } 123611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 123711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 123811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 123911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 124011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return !(nullptr < __a); } 124111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 124211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 124311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 124411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 124511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return !(__a < nullptr); } 124611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 124711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 124811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 124911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator>(const __shared_ptr<_Tp1, _Lp>& __a, 125011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const __shared_ptr<_Tp2, _Lp>& __b) noexcept 125111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return (__b < __a); } 125211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 125311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 125411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 125511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 125611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return std::less<_Tp*>()(nullptr, __a.get()); } 125711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 125811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 125911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 126011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 126111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return std::less<_Tp*>()(__a.get(), nullptr); } 126211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 126311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename _Tp2, _Lock_policy _Lp> 126411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 126511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator>=(const __shared_ptr<_Tp1, _Lp>& __a, 126611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const __shared_ptr<_Tp2, _Lp>& __b) noexcept 126711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return !(__a < __b); } 126811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 126911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 127011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 127111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept 127211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return !(__a < nullptr); } 127311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 127411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 127511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 127611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept 127711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return !(nullptr < __a); } 127811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 127911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Sp> 128011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Sp_less : public binary_function<_Sp, _Sp, bool> 128111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 128211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 128311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept 128411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 128511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename _Sp::element_type element_type; 128611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return std::less<element_type*>()(__lhs.get(), __rhs.get()); 128711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 128811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 128911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 129011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 129111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct less<__shared_ptr<_Tp, _Lp>> 129211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : public _Sp_less<__shared_ptr<_Tp, _Lp>> 129311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { }; 129411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 129511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 20.7.2.2.8 shared_ptr specialized algorithms. 129611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 129711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 129811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept 129911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { __a.swap(__b); } 130011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 130111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 20.7.2.2.9 shared_ptr casts 130211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 130311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // The seemingly equivalent code: 130411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get())) 130511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // will eventually result in undefined behaviour, attempting to 130611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // delete the same object twice. 130711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// static_pointer_cast 130811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 130911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline __shared_ptr<_Tp, _Lp> 131011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 131111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); } 131211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 131311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // The seemingly equivalent code: 131411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get())) 131511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // will eventually result in undefined behaviour, attempting to 131611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // delete the same object twice. 131711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// const_pointer_cast 131811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 131911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline __shared_ptr<_Tp, _Lp> 132011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 132111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); } 132211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 132311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // The seemingly equivalent code: 132411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get())) 132511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // will eventually result in undefined behaviour, attempting to 132611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // delete the same object twice. 132711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// dynamic_pointer_cast 132811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 132911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline __shared_ptr<_Tp, _Lp> 133011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 133111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 133211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_Tp* __p = dynamic_cast<_Tp*>(__r.get())) 133311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __shared_ptr<_Tp, _Lp>(__r, __p); 133411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __shared_ptr<_Tp, _Lp>(); 133511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 133611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 133711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 133811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 133911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class __weak_ptr 134011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 134111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 134211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Tp element_type; 134311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 134411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert constexpr __weak_ptr() noexcept 134511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(0), _M_refcount() 134611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 134711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 134811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __weak_ptr(const __weak_ptr&) noexcept = default; 134911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __weak_ptr& operator=(const __weak_ptr&) noexcept = default; 135011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~__weak_ptr() = default; 135111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 135211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // The "obvious" converting constructor implementation: 135311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 135411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // template<typename _Tp1> 135511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 135611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 135711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // { } 135811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 135911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // has a serious problem. 136011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 136111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 136211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // conversion may require access to *__r._M_ptr (virtual inheritance). 136311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 136411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // It is not possible to avoid spurious access violations since 136511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // in multithreaded programs __r._M_ptr may be invalidated at any point. 136611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename = typename 136711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 136811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) noexcept 136911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_refcount(__r._M_refcount) 137011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _M_ptr = __r.lock().get(); } 137111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 137211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, typename = typename 137311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> 137411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 137511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) 137611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { } 137711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 137811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 137911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __weak_ptr& 138011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept 138111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 138211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ptr = __r.lock().get(); 138311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount = __r._M_refcount; 138411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 138511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 138611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 138711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 138811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __weak_ptr& 138911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept 139011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 139111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ptr = __r._M_ptr; 139211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount = __r._M_refcount; 139311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return *this; 139411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 139511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 139611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr<_Tp, _Lp> 139711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert lock() const noexcept 139811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); } 139911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 140011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert long 140111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert use_count() const noexcept 140211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_refcount._M_get_use_count(); } 140311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 140411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 140511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert expired() const noexcept 140611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_refcount._M_get_use_count() == 0; } 140711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 140811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 140911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 141011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const 141111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_refcount._M_less(__rhs._M_refcount); } 141211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 141311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 141411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 141511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const 141611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_refcount._M_less(__rhs._M_refcount); } 141711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 141811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 141911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert reset() noexcept 142011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { __weak_ptr().swap(*this); } 142111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 142211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 142311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert swap(__weak_ptr& __s) noexcept 142411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 142511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::swap(_M_ptr, __s._M_ptr); 142611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount._M_swap(__s._M_refcount); 142711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 142811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 142911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 143011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Used by __enable_shared_from_this. 143111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 143211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept 143311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 143411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_ptr = __ptr; 143511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount = __refcount; 143611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 143711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 143811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 143911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 144011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert friend class __enable_shared_from_this<_Tp, _Lp>; 144111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert friend class enable_shared_from_this<_Tp>; 144211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 144311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Tp* _M_ptr; // Contained pointer. 144411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __weak_count<_Lp> _M_refcount; // Reference counter. 144511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 144611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 144711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 20.7.2.3.6 weak_ptr specialized algorithms. 144811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 144911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline void 145011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept 145111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { __a.swap(__b); } 145211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 145311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, typename _Tp1> 145411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool> 145511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 145611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 145711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator()(const _Tp& __lhs, const _Tp& __rhs) const 145811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __lhs.owner_before(__rhs); } 145911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 146011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 146111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator()(const _Tp& __lhs, const _Tp1& __rhs) const 146211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __lhs.owner_before(__rhs); } 146311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 146411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 146511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator()(const _Tp1& __lhs, const _Tp& __rhs) const 146611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __lhs.owner_before(__rhs); } 146711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 146811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 146911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 147011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct owner_less<__shared_ptr<_Tp, _Lp>> 147111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>> 147211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { }; 147311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 147411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 147511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct owner_less<__weak_ptr<_Tp, _Lp>> 147611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>> 147711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { }; 147811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 147911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 148011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 148111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class __enable_shared_from_this 148211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 148311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert protected: 148411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert constexpr __enable_shared_from_this() noexcept { } 148511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 148611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this(const __enable_shared_from_this&) noexcept { } 148711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 148811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this& 148911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator=(const __enable_shared_from_this&) noexcept 149011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return *this; } 149111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 149211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~__enable_shared_from_this() { } 149311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 149411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 149511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr<_Tp, _Lp> 149611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert shared_from_this() 149711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 149811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 149911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __shared_ptr<const _Tp, _Lp> 150011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert shared_from_this() const 150111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } 150211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 150311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 150411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 150511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 150611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept 150711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _M_weak_this._M_assign(__p, __n); } 150811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 150911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp1> 151011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert friend void 151111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, 151211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const __enable_shared_from_this* __pe, 151311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Tp1* __px) noexcept 151411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 151511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__pe != 0) 151611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 151711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 151811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 151911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 152011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 152111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 152211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 152311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args> 152411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline __shared_ptr<_Tp, _Lp> 152511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __allocate_shared(const _Alloc& __a, _Args&&... __args) 152611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 152711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a, 152811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::forward<_Args>(__args)...); 152911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 153011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 153111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp, typename... _Args> 153211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline __shared_ptr<_Tp, _Lp> 153311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __make_shared(_Args&&... __args) 153411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 153511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename std::remove_const<_Tp>::type _Tp_nc; 153611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(), 153711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::forward<_Args>(__args)...); 153811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 153911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 154011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /// std::hash specialization for __shared_ptr. 154111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Tp, _Lock_policy _Lp> 154211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct hash<__shared_ptr<_Tp, _Lp>> 154311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>> 154411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 154511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_t 154611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept 154711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return std::hash<_Tp*>()(__s.get()); } 154811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 154911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 155011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_GLIBCXX_END_NAMESPACE_VERSION 155111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // namespace 155211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 155311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif // _SHARED_PTR_BASE_H 1554