138fd1498Szrj // shared_ptr and weak_ptr implementation -*- C++ -*- 238fd1498Szrj 338fd1498Szrj // Copyright (C) 2007-2018 Free Software Foundation, Inc. 438fd1498Szrj // 538fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 638fd1498Szrj // software; you can redistribute it and/or modify it under the 738fd1498Szrj // terms of the GNU General Public License as published by the 838fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 938fd1498Szrj // any later version. 1038fd1498Szrj 1138fd1498Szrj // This library is distributed in the hope that it will be useful, 1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1438fd1498Szrj // GNU General Public License for more details. 1538fd1498Szrj 1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 1838fd1498Szrj // 3.1, as published by the Free Software Foundation. 1938fd1498Szrj 2038fd1498Szrj // You should have received a copy of the GNU General Public License and 2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2338fd1498Szrj // <http://www.gnu.org/licenses/>. 2438fd1498Szrj 2538fd1498Szrj // GCC Note: Based on files from version 1.32.0 of the Boost library. 2638fd1498Szrj 2738fd1498Szrj // shared_count.hpp 2838fd1498Szrj // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 2938fd1498Szrj 3038fd1498Szrj // shared_ptr.hpp 3138fd1498Szrj // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. 3238fd1498Szrj // Copyright (C) 2001, 2002, 2003 Peter Dimov 3338fd1498Szrj 3438fd1498Szrj // weak_ptr.hpp 3538fd1498Szrj // Copyright (C) 2001, 2002, 2003 Peter Dimov 3638fd1498Szrj 3738fd1498Szrj // enable_shared_from_this.hpp 3838fd1498Szrj // Copyright (C) 2002 Peter Dimov 3938fd1498Szrj 4038fd1498Szrj // Distributed under the Boost Software License, Version 1.0. (See 4138fd1498Szrj // accompanying file LICENSE_1_0.txt or copy at 4238fd1498Szrj // http://www.boost.org/LICENSE_1_0.txt) 4338fd1498Szrj 4438fd1498Szrj /** @file 4538fd1498Szrj * This is an internal header file, included by other library headers. 4638fd1498Szrj * Do not attempt to use it directly. @headername{memory} 4738fd1498Szrj */ 4838fd1498Szrj 4938fd1498Szrj #ifndef _SHARED_PTR_H 5038fd1498Szrj #define _SHARED_PTR_H 1 5138fd1498Szrj 5238fd1498Szrj #include <bits/shared_ptr_base.h> 5338fd1498Szrj 5438fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 5538fd1498Szrj { 5638fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 5738fd1498Szrj 5838fd1498Szrj /** 5938fd1498Szrj * @addtogroup pointer_abstractions 6038fd1498Szrj * @{ 6138fd1498Szrj */ 6238fd1498Szrj 6338fd1498Szrj /// 20.7.2.2.11 shared_ptr I/O 6438fd1498Szrj template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> 6538fd1498Szrj inline std::basic_ostream<_Ch, _Tr>& 6638fd1498Szrj operator<<(std::basic_ostream<_Ch, _Tr>& __os, 6738fd1498Szrj const __shared_ptr<_Tp, _Lp>& __p) 6838fd1498Szrj { 6938fd1498Szrj __os << __p.get(); 7038fd1498Szrj return __os; 7138fd1498Szrj } 7238fd1498Szrj 7338fd1498Szrj template<typename _Del, typename _Tp, _Lock_policy _Lp> 7438fd1498Szrj inline _Del* 7538fd1498Szrj get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept 7638fd1498Szrj { 7738fd1498Szrj #if __cpp_rtti 7838fd1498Szrj return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 7938fd1498Szrj #else 8038fd1498Szrj return 0; 8138fd1498Szrj #endif 8238fd1498Szrj } 8338fd1498Szrj 8438fd1498Szrj /// 20.7.2.2.10 shared_ptr get_deleter 8538fd1498Szrj template<typename _Del, typename _Tp> 8638fd1498Szrj inline _Del* 8738fd1498Szrj get_deleter(const shared_ptr<_Tp>& __p) noexcept 8838fd1498Szrj { 8938fd1498Szrj #if __cpp_rtti 9038fd1498Szrj return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 9138fd1498Szrj #else 9238fd1498Szrj return 0; 9338fd1498Szrj #endif 9438fd1498Szrj } 9538fd1498Szrj 9638fd1498Szrj /** 9738fd1498Szrj * @brief A smart pointer with reference-counted copy semantics. 9838fd1498Szrj * 9938fd1498Szrj * The object pointed to is deleted when the last shared_ptr pointing to 10038fd1498Szrj * it is destroyed or reset. 10138fd1498Szrj */ 10238fd1498Szrj template<typename _Tp> 10338fd1498Szrj class shared_ptr : public __shared_ptr<_Tp> 10438fd1498Szrj { 10538fd1498Szrj template<typename... _Args> 10638fd1498Szrj using _Constructible = typename enable_if< 10738fd1498Szrj is_constructible<__shared_ptr<_Tp>, _Args...>::value 10838fd1498Szrj >::type; 10938fd1498Szrj 11038fd1498Szrj template<typename _Arg> 11138fd1498Szrj using _Assignable = typename enable_if< 11238fd1498Szrj is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr& 11338fd1498Szrj >::type; 11438fd1498Szrj 11538fd1498Szrj public: 11638fd1498Szrj 11738fd1498Szrj using element_type = typename __shared_ptr<_Tp>::element_type; 11838fd1498Szrj 11938fd1498Szrj #if __cplusplus > 201402L 12038fd1498Szrj # define __cpp_lib_shared_ptr_weak_type 201606 12138fd1498Szrj using weak_type = weak_ptr<_Tp>; 12238fd1498Szrj #endif 12338fd1498Szrj /** 12438fd1498Szrj * @brief Construct an empty %shared_ptr. 12538fd1498Szrj * @post use_count()==0 && get()==0 12638fd1498Szrj */ 12738fd1498Szrj constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { } 12838fd1498Szrj 12938fd1498Szrj shared_ptr(const shared_ptr&) noexcept = default; 13038fd1498Szrj 13138fd1498Szrj /** 13238fd1498Szrj * @brief Construct a %shared_ptr that owns the pointer @a __p. 13338fd1498Szrj * @param __p A pointer that is convertible to element_type*. 13438fd1498Szrj * @post use_count() == 1 && get() == __p 13538fd1498Szrj * @throw std::bad_alloc, in which case @c delete @a __p is called. 13638fd1498Szrj */ 13738fd1498Szrj template<typename _Yp, typename = _Constructible<_Yp*>> 13838fd1498Szrj explicit 13938fd1498Szrj shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { } 14038fd1498Szrj 14138fd1498Szrj /** 14238fd1498Szrj * @brief Construct a %shared_ptr that owns the pointer @a __p 14338fd1498Szrj * and the deleter @a __d. 14438fd1498Szrj * @param __p A pointer. 14538fd1498Szrj * @param __d A deleter. 14638fd1498Szrj * @post use_count() == 1 && get() == __p 14738fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called. 14838fd1498Szrj * 14938fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must 15038fd1498Szrj * not throw 15138fd1498Szrj * 15238fd1498Szrj * __shared_ptr will release __p by calling __d(__p) 15338fd1498Szrj */ 15438fd1498Szrj template<typename _Yp, typename _Deleter, 15538fd1498Szrj typename = _Constructible<_Yp*, _Deleter>> 15638fd1498Szrj shared_ptr(_Yp* __p, _Deleter __d) 15738fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d)) { } 15838fd1498Szrj 15938fd1498Szrj /** 16038fd1498Szrj * @brief Construct a %shared_ptr that owns a null pointer 16138fd1498Szrj * and the deleter @a __d. 16238fd1498Szrj * @param __p A null pointer constant. 16338fd1498Szrj * @param __d A deleter. 16438fd1498Szrj * @post use_count() == 1 && get() == __p 16538fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called. 16638fd1498Szrj * 16738fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must 16838fd1498Szrj * not throw 16938fd1498Szrj * 17038fd1498Szrj * The last owner will call __d(__p) 17138fd1498Szrj */ 17238fd1498Szrj template<typename _Deleter> 17338fd1498Szrj shared_ptr(nullptr_t __p, _Deleter __d) 17438fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d)) { } 17538fd1498Szrj 17638fd1498Szrj /** 17738fd1498Szrj * @brief Construct a %shared_ptr that owns the pointer @a __p 17838fd1498Szrj * and the deleter @a __d. 17938fd1498Szrj * @param __p A pointer. 18038fd1498Szrj * @param __d A deleter. 18138fd1498Szrj * @param __a An allocator. 18238fd1498Szrj * @post use_count() == 1 && get() == __p 18338fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called. 18438fd1498Szrj * 18538fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must 18638fd1498Szrj * not throw _Alloc's copy constructor and destructor must not 18738fd1498Szrj * throw. 18838fd1498Szrj * 18938fd1498Szrj * __shared_ptr will release __p by calling __d(__p) 19038fd1498Szrj */ 19138fd1498Szrj template<typename _Yp, typename _Deleter, typename _Alloc, 19238fd1498Szrj typename = _Constructible<_Yp*, _Deleter, _Alloc>> 19338fd1498Szrj shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a) 19438fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } 19538fd1498Szrj 19638fd1498Szrj /** 19738fd1498Szrj * @brief Construct a %shared_ptr that owns a null pointer 19838fd1498Szrj * and the deleter @a __d. 19938fd1498Szrj * @param __p A null pointer constant. 20038fd1498Szrj * @param __d A deleter. 20138fd1498Szrj * @param __a An allocator. 20238fd1498Szrj * @post use_count() == 1 && get() == __p 20338fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called. 20438fd1498Szrj * 20538fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must 20638fd1498Szrj * not throw _Alloc's copy constructor and destructor must not 20738fd1498Szrj * throw. 20838fd1498Szrj * 20938fd1498Szrj * The last owner will call __d(__p) 21038fd1498Szrj */ 21138fd1498Szrj template<typename _Deleter, typename _Alloc> 21238fd1498Szrj shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 21338fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } 21438fd1498Szrj 21538fd1498Szrj // Aliasing constructor 21638fd1498Szrj 21738fd1498Szrj /** 21838fd1498Szrj * @brief Constructs a %shared_ptr instance that stores @a __p 21938fd1498Szrj * and shares ownership with @a __r. 22038fd1498Szrj * @param __r A %shared_ptr. 22138fd1498Szrj * @param __p A pointer that will remain valid while @a *__r is valid. 22238fd1498Szrj * @post get() == __p && use_count() == __r.use_count() 22338fd1498Szrj * 22438fd1498Szrj * This can be used to construct a @c shared_ptr to a sub-object 22538fd1498Szrj * of an object managed by an existing @c shared_ptr. 22638fd1498Szrj * 22738fd1498Szrj * @code 22838fd1498Szrj * shared_ptr< pair<int,int> > pii(new pair<int,int>()); 22938fd1498Szrj * shared_ptr<int> pi(pii, &pii->first); 23038fd1498Szrj * assert(pii.use_count() == 2); 23138fd1498Szrj * @endcode 23238fd1498Szrj */ 23338fd1498Szrj template<typename _Yp> 23438fd1498Szrj shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept 23538fd1498Szrj : __shared_ptr<_Tp>(__r, __p) { } 23638fd1498Szrj 23738fd1498Szrj /** 23838fd1498Szrj * @brief If @a __r is empty, constructs an empty %shared_ptr; 23938fd1498Szrj * otherwise construct a %shared_ptr that shares ownership 24038fd1498Szrj * with @a __r. 24138fd1498Szrj * @param __r A %shared_ptr. 24238fd1498Szrj * @post get() == __r.get() && use_count() == __r.use_count() 24338fd1498Szrj */ 24438fd1498Szrj template<typename _Yp, 24538fd1498Szrj typename = _Constructible<const shared_ptr<_Yp>&>> 24638fd1498Szrj shared_ptr(const shared_ptr<_Yp>& __r) noexcept 24738fd1498Szrj : __shared_ptr<_Tp>(__r) { } 24838fd1498Szrj 24938fd1498Szrj /** 25038fd1498Szrj * @brief Move-constructs a %shared_ptr instance from @a __r. 25138fd1498Szrj * @param __r A %shared_ptr rvalue. 25238fd1498Szrj * @post *this contains the old value of @a __r, @a __r is empty. 25338fd1498Szrj */ 25438fd1498Szrj shared_ptr(shared_ptr&& __r) noexcept 25538fd1498Szrj : __shared_ptr<_Tp>(std::move(__r)) { } 25638fd1498Szrj 25738fd1498Szrj /** 25838fd1498Szrj * @brief Move-constructs a %shared_ptr instance from @a __r. 25938fd1498Szrj * @param __r A %shared_ptr rvalue. 26038fd1498Szrj * @post *this contains the old value of @a __r, @a __r is empty. 26138fd1498Szrj */ 26238fd1498Szrj template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>> 26338fd1498Szrj shared_ptr(shared_ptr<_Yp>&& __r) noexcept 26438fd1498Szrj : __shared_ptr<_Tp>(std::move(__r)) { } 26538fd1498Szrj 26638fd1498Szrj /** 26738fd1498Szrj * @brief Constructs a %shared_ptr that shares ownership with @a __r 26838fd1498Szrj * and stores a copy of the pointer stored in @a __r. 26938fd1498Szrj * @param __r A weak_ptr. 27038fd1498Szrj * @post use_count() == __r.use_count() 27138fd1498Szrj * @throw bad_weak_ptr when __r.expired(), 27238fd1498Szrj * in which case the constructor has no effect. 27338fd1498Szrj */ 27438fd1498Szrj template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> 27538fd1498Szrj explicit shared_ptr(const weak_ptr<_Yp>& __r) 27638fd1498Szrj : __shared_ptr<_Tp>(__r) { } 27738fd1498Szrj 27838fd1498Szrj #if _GLIBCXX_USE_DEPRECATED 27938fd1498Szrj #pragma GCC diagnostic push 28038fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 28138fd1498Szrj template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>> 28238fd1498Szrj shared_ptr(auto_ptr<_Yp>&& __r); 28338fd1498Szrj #pragma GCC diagnostic pop 28438fd1498Szrj #endif 28538fd1498Szrj 28638fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 28738fd1498Szrj // 2399. shared_ptr's constructor from unique_ptr should be constrained 28838fd1498Szrj template<typename _Yp, typename _Del, 28938fd1498Szrj typename = _Constructible<unique_ptr<_Yp, _Del>>> 29038fd1498Szrj shared_ptr(unique_ptr<_Yp, _Del>&& __r) 29138fd1498Szrj : __shared_ptr<_Tp>(std::move(__r)) { } 29238fd1498Szrj 29338fd1498Szrj #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED 29438fd1498Szrj // This non-standard constructor exists to support conversions that 29538fd1498Szrj // were possible in C++11 and C++14 but are ill-formed in C++17. 29638fd1498Szrj // If an exception is thrown this constructor has no effect. 29738fd1498Szrj template<typename _Yp, typename _Del, 29838fd1498Szrj _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0> 29938fd1498Szrj shared_ptr(unique_ptr<_Yp, _Del>&& __r) 30038fd1498Szrj : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { } 30138fd1498Szrj #endif 30238fd1498Szrj 30338fd1498Szrj /** 30438fd1498Szrj * @brief Construct an empty %shared_ptr. 30538fd1498Szrj * @post use_count() == 0 && get() == nullptr 30638fd1498Szrj */ 30738fd1498Szrj constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { } 30838fd1498Szrj 30938fd1498Szrj shared_ptr& operator=(const shared_ptr&) noexcept = default; 31038fd1498Szrj 31138fd1498Szrj template<typename _Yp> 31238fd1498Szrj _Assignable<const shared_ptr<_Yp>&> 31338fd1498Szrj operator=(const shared_ptr<_Yp>& __r) noexcept 31438fd1498Szrj { 31538fd1498Szrj this->__shared_ptr<_Tp>::operator=(__r); 31638fd1498Szrj return *this; 31738fd1498Szrj } 31838fd1498Szrj 31938fd1498Szrj #if _GLIBCXX_USE_DEPRECATED 32038fd1498Szrj #pragma GCC diagnostic push 32138fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 32238fd1498Szrj template<typename _Yp> 32338fd1498Szrj _Assignable<auto_ptr<_Yp>> 32438fd1498Szrj operator=(auto_ptr<_Yp>&& __r) 32538fd1498Szrj { 32638fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r)); 32738fd1498Szrj return *this; 32838fd1498Szrj } 32938fd1498Szrj #pragma GCC diagnostic pop 33038fd1498Szrj #endif 33138fd1498Szrj 33238fd1498Szrj shared_ptr& 33338fd1498Szrj operator=(shared_ptr&& __r) noexcept 33438fd1498Szrj { 33538fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r)); 33638fd1498Szrj return *this; 33738fd1498Szrj } 33838fd1498Szrj 33938fd1498Szrj template<class _Yp> 34038fd1498Szrj _Assignable<shared_ptr<_Yp>> 34138fd1498Szrj operator=(shared_ptr<_Yp>&& __r) noexcept 34238fd1498Szrj { 34338fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r)); 34438fd1498Szrj return *this; 34538fd1498Szrj } 34638fd1498Szrj 34738fd1498Szrj template<typename _Yp, typename _Del> 34838fd1498Szrj _Assignable<unique_ptr<_Yp, _Del>> 34938fd1498Szrj operator=(unique_ptr<_Yp, _Del>&& __r) 35038fd1498Szrj { 35138fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r)); 35238fd1498Szrj return *this; 35338fd1498Szrj } 35438fd1498Szrj 35538fd1498Szrj private: 35638fd1498Szrj // This constructor is non-standard, it is used by allocate_shared. 35738fd1498Szrj template<typename _Alloc, typename... _Args> 358*58e805e6Szrj shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args) 359*58e805e6Szrj : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...) 36038fd1498Szrj { } 36138fd1498Szrj 36238fd1498Szrj template<typename _Yp, typename _Alloc, typename... _Args> 36338fd1498Szrj friend shared_ptr<_Yp> 36438fd1498Szrj allocate_shared(const _Alloc& __a, _Args&&... __args); 36538fd1498Szrj 36638fd1498Szrj // This constructor is non-standard, it is used by weak_ptr::lock(). 36738fd1498Szrj shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) 36838fd1498Szrj : __shared_ptr<_Tp>(__r, std::nothrow) { } 36938fd1498Szrj 37038fd1498Szrj friend class weak_ptr<_Tp>; 37138fd1498Szrj }; 37238fd1498Szrj 37338fd1498Szrj #if __cpp_deduction_guides >= 201606 37438fd1498Szrj template<typename _Tp> 37538fd1498Szrj shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; 37638fd1498Szrj template<typename _Tp, typename _Del> 37738fd1498Szrj shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>; 37838fd1498Szrj #endif 37938fd1498Szrj 38038fd1498Szrj // 20.7.2.2.7 shared_ptr comparisons 38138fd1498Szrj template<typename _Tp, typename _Up> 38238fd1498Szrj inline bool 38338fd1498Szrj operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 38438fd1498Szrj { return __a.get() == __b.get(); } 38538fd1498Szrj 38638fd1498Szrj template<typename _Tp> 38738fd1498Szrj inline bool 38838fd1498Szrj operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 38938fd1498Szrj { return !__a; } 39038fd1498Szrj 39138fd1498Szrj template<typename _Tp> 39238fd1498Szrj inline bool 39338fd1498Szrj operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 39438fd1498Szrj { return !__a; } 39538fd1498Szrj 39638fd1498Szrj template<typename _Tp, typename _Up> 39738fd1498Szrj inline bool 39838fd1498Szrj operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 39938fd1498Szrj { return __a.get() != __b.get(); } 40038fd1498Szrj 40138fd1498Szrj template<typename _Tp> 40238fd1498Szrj inline bool 40338fd1498Szrj operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 40438fd1498Szrj { return (bool)__a; } 40538fd1498Szrj 40638fd1498Szrj template<typename _Tp> 40738fd1498Szrj inline bool 40838fd1498Szrj operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 40938fd1498Szrj { return (bool)__a; } 41038fd1498Szrj 41138fd1498Szrj template<typename _Tp, typename _Up> 41238fd1498Szrj inline bool 41338fd1498Szrj operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 41438fd1498Szrj { 41538fd1498Szrj using _Tp_elt = typename shared_ptr<_Tp>::element_type; 41638fd1498Szrj using _Up_elt = typename shared_ptr<_Up>::element_type; 41738fd1498Szrj using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; 41838fd1498Szrj return less<_Vp>()(__a.get(), __b.get()); 41938fd1498Szrj } 42038fd1498Szrj 42138fd1498Szrj template<typename _Tp> 42238fd1498Szrj inline bool 42338fd1498Szrj operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 42438fd1498Szrj { 42538fd1498Szrj using _Tp_elt = typename shared_ptr<_Tp>::element_type; 42638fd1498Szrj return less<_Tp_elt*>()(__a.get(), nullptr); 42738fd1498Szrj } 42838fd1498Szrj 42938fd1498Szrj template<typename _Tp> 43038fd1498Szrj inline bool 43138fd1498Szrj operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 43238fd1498Szrj { 43338fd1498Szrj using _Tp_elt = typename shared_ptr<_Tp>::element_type; 43438fd1498Szrj return less<_Tp_elt*>()(nullptr, __a.get()); 43538fd1498Szrj } 43638fd1498Szrj 43738fd1498Szrj template<typename _Tp, typename _Up> 43838fd1498Szrj inline bool 43938fd1498Szrj operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 44038fd1498Szrj { return !(__b < __a); } 44138fd1498Szrj 44238fd1498Szrj template<typename _Tp> 44338fd1498Szrj inline bool 44438fd1498Szrj operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 44538fd1498Szrj { return !(nullptr < __a); } 44638fd1498Szrj 44738fd1498Szrj template<typename _Tp> 44838fd1498Szrj inline bool 44938fd1498Szrj operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 45038fd1498Szrj { return !(__a < nullptr); } 45138fd1498Szrj 45238fd1498Szrj template<typename _Tp, typename _Up> 45338fd1498Szrj inline bool 45438fd1498Szrj operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 45538fd1498Szrj { return (__b < __a); } 45638fd1498Szrj 45738fd1498Szrj template<typename _Tp> 45838fd1498Szrj inline bool 45938fd1498Szrj operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 46038fd1498Szrj { return nullptr < __a; } 46138fd1498Szrj 46238fd1498Szrj template<typename _Tp> 46338fd1498Szrj inline bool 46438fd1498Szrj operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 46538fd1498Szrj { return __a < nullptr; } 46638fd1498Szrj 46738fd1498Szrj template<typename _Tp, typename _Up> 46838fd1498Szrj inline bool 46938fd1498Szrj operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 47038fd1498Szrj { return !(__a < __b); } 47138fd1498Szrj 47238fd1498Szrj template<typename _Tp> 47338fd1498Szrj inline bool 47438fd1498Szrj operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 47538fd1498Szrj { return !(__a < nullptr); } 47638fd1498Szrj 47738fd1498Szrj template<typename _Tp> 47838fd1498Szrj inline bool 47938fd1498Szrj operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 48038fd1498Szrj { return !(nullptr < __a); } 48138fd1498Szrj 48238fd1498Szrj template<typename _Tp> 48338fd1498Szrj struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> 48438fd1498Szrj { }; 48538fd1498Szrj 48638fd1498Szrj // 20.7.2.2.8 shared_ptr specialized algorithms. 48738fd1498Szrj template<typename _Tp> 48838fd1498Szrj inline void 48938fd1498Szrj swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept 49038fd1498Szrj { __a.swap(__b); } 49138fd1498Szrj 49238fd1498Szrj // 20.7.2.2.9 shared_ptr casts. 49338fd1498Szrj template<typename _Tp, typename _Up> 49438fd1498Szrj inline shared_ptr<_Tp> 49538fd1498Szrj static_pointer_cast(const shared_ptr<_Up>& __r) noexcept 49638fd1498Szrj { 49738fd1498Szrj using _Sp = shared_ptr<_Tp>; 49838fd1498Szrj return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get())); 49938fd1498Szrj } 50038fd1498Szrj 50138fd1498Szrj template<typename _Tp, typename _Up> 50238fd1498Szrj inline shared_ptr<_Tp> 50338fd1498Szrj const_pointer_cast(const shared_ptr<_Up>& __r) noexcept 50438fd1498Szrj { 50538fd1498Szrj using _Sp = shared_ptr<_Tp>; 50638fd1498Szrj return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get())); 50738fd1498Szrj } 50838fd1498Szrj 50938fd1498Szrj template<typename _Tp, typename _Up> 51038fd1498Szrj inline shared_ptr<_Tp> 51138fd1498Szrj dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept 51238fd1498Szrj { 51338fd1498Szrj using _Sp = shared_ptr<_Tp>; 51438fd1498Szrj if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get())) 51538fd1498Szrj return _Sp(__r, __p); 51638fd1498Szrj return _Sp(); 51738fd1498Szrj } 51838fd1498Szrj 51938fd1498Szrj #if __cplusplus > 201402L 52038fd1498Szrj template<typename _Tp, typename _Up> 52138fd1498Szrj inline shared_ptr<_Tp> 52238fd1498Szrj reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept 52338fd1498Szrj { 52438fd1498Szrj using _Sp = shared_ptr<_Tp>; 52538fd1498Szrj return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get())); 52638fd1498Szrj } 52738fd1498Szrj #endif 52838fd1498Szrj 52938fd1498Szrj /** 53038fd1498Szrj * @brief A smart pointer with weak semantics. 53138fd1498Szrj * 53238fd1498Szrj * With forwarding constructors and assignment operators. 53338fd1498Szrj */ 53438fd1498Szrj template<typename _Tp> 53538fd1498Szrj class weak_ptr : public __weak_ptr<_Tp> 53638fd1498Szrj { 53738fd1498Szrj template<typename _Arg> 53838fd1498Szrj using _Constructible = typename enable_if< 53938fd1498Szrj is_constructible<__weak_ptr<_Tp>, _Arg>::value 54038fd1498Szrj >::type; 54138fd1498Szrj 54238fd1498Szrj template<typename _Arg> 54338fd1498Szrj using _Assignable = typename enable_if< 54438fd1498Szrj is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr& 54538fd1498Szrj >::type; 54638fd1498Szrj 54738fd1498Szrj public: 54838fd1498Szrj constexpr weak_ptr() noexcept = default; 54938fd1498Szrj 55038fd1498Szrj template<typename _Yp, 55138fd1498Szrj typename = _Constructible<const shared_ptr<_Yp>&>> 55238fd1498Szrj weak_ptr(const shared_ptr<_Yp>& __r) noexcept 55338fd1498Szrj : __weak_ptr<_Tp>(__r) { } 55438fd1498Szrj 55538fd1498Szrj weak_ptr(const weak_ptr&) noexcept = default; 55638fd1498Szrj 55738fd1498Szrj template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> 55838fd1498Szrj weak_ptr(const weak_ptr<_Yp>& __r) noexcept 55938fd1498Szrj : __weak_ptr<_Tp>(__r) { } 56038fd1498Szrj 56138fd1498Szrj weak_ptr(weak_ptr&&) noexcept = default; 56238fd1498Szrj 56338fd1498Szrj template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>> 56438fd1498Szrj weak_ptr(weak_ptr<_Yp>&& __r) noexcept 56538fd1498Szrj : __weak_ptr<_Tp>(std::move(__r)) { } 56638fd1498Szrj 56738fd1498Szrj weak_ptr& 56838fd1498Szrj operator=(const weak_ptr& __r) noexcept = default; 56938fd1498Szrj 57038fd1498Szrj template<typename _Yp> 57138fd1498Szrj _Assignable<const weak_ptr<_Yp>&> 57238fd1498Szrj operator=(const weak_ptr<_Yp>& __r) noexcept 57338fd1498Szrj { 57438fd1498Szrj this->__weak_ptr<_Tp>::operator=(__r); 57538fd1498Szrj return *this; 57638fd1498Szrj } 57738fd1498Szrj 57838fd1498Szrj template<typename _Yp> 57938fd1498Szrj _Assignable<const shared_ptr<_Yp>&> 58038fd1498Szrj operator=(const shared_ptr<_Yp>& __r) noexcept 58138fd1498Szrj { 58238fd1498Szrj this->__weak_ptr<_Tp>::operator=(__r); 58338fd1498Szrj return *this; 58438fd1498Szrj } 58538fd1498Szrj 58638fd1498Szrj weak_ptr& 58738fd1498Szrj operator=(weak_ptr&& __r) noexcept = default; 58838fd1498Szrj 58938fd1498Szrj template<typename _Yp> 59038fd1498Szrj _Assignable<weak_ptr<_Yp>> 59138fd1498Szrj operator=(weak_ptr<_Yp>&& __r) noexcept 59238fd1498Szrj { 59338fd1498Szrj this->__weak_ptr<_Tp>::operator=(std::move(__r)); 59438fd1498Szrj return *this; 59538fd1498Szrj } 59638fd1498Szrj 59738fd1498Szrj shared_ptr<_Tp> 59838fd1498Szrj lock() const noexcept 59938fd1498Szrj { return shared_ptr<_Tp>(*this, std::nothrow); } 60038fd1498Szrj }; 60138fd1498Szrj 60238fd1498Szrj #if __cpp_deduction_guides >= 201606 60338fd1498Szrj template<typename _Tp> 60438fd1498Szrj weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; 60538fd1498Szrj #endif 60638fd1498Szrj 60738fd1498Szrj // 20.7.2.3.6 weak_ptr specialized algorithms. 60838fd1498Szrj template<typename _Tp> 60938fd1498Szrj inline void 61038fd1498Szrj swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept 61138fd1498Szrj { __a.swap(__b); } 61238fd1498Szrj 61338fd1498Szrj 61438fd1498Szrj /// Primary template owner_less 61538fd1498Szrj template<typename _Tp = void> 61638fd1498Szrj struct owner_less; 61738fd1498Szrj 61838fd1498Szrj /// Void specialization of owner_less 61938fd1498Szrj template<> 62038fd1498Szrj struct owner_less<void> : _Sp_owner_less<void, void> 62138fd1498Szrj { }; 62238fd1498Szrj 62338fd1498Szrj /// Partial specialization of owner_less for shared_ptr. 62438fd1498Szrj template<typename _Tp> 62538fd1498Szrj struct owner_less<shared_ptr<_Tp>> 62638fd1498Szrj : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> 62738fd1498Szrj { }; 62838fd1498Szrj 62938fd1498Szrj /// Partial specialization of owner_less for weak_ptr. 63038fd1498Szrj template<typename _Tp> 63138fd1498Szrj struct owner_less<weak_ptr<_Tp>> 63238fd1498Szrj : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> 63338fd1498Szrj { }; 63438fd1498Szrj 63538fd1498Szrj /** 63638fd1498Szrj * @brief Base class allowing use of member function shared_from_this. 63738fd1498Szrj */ 63838fd1498Szrj template<typename _Tp> 63938fd1498Szrj class enable_shared_from_this 64038fd1498Szrj { 64138fd1498Szrj protected: 64238fd1498Szrj constexpr enable_shared_from_this() noexcept { } 64338fd1498Szrj 64438fd1498Szrj enable_shared_from_this(const enable_shared_from_this&) noexcept { } 64538fd1498Szrj 64638fd1498Szrj enable_shared_from_this& 64738fd1498Szrj operator=(const enable_shared_from_this&) noexcept 64838fd1498Szrj { return *this; } 64938fd1498Szrj 65038fd1498Szrj ~enable_shared_from_this() { } 65138fd1498Szrj 65238fd1498Szrj public: 65338fd1498Szrj shared_ptr<_Tp> 65438fd1498Szrj shared_from_this() 65538fd1498Szrj { return shared_ptr<_Tp>(this->_M_weak_this); } 65638fd1498Szrj 65738fd1498Szrj shared_ptr<const _Tp> 65838fd1498Szrj shared_from_this() const 65938fd1498Szrj { return shared_ptr<const _Tp>(this->_M_weak_this); } 66038fd1498Szrj 66138fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 66238fd1498Szrj #define __cpp_lib_enable_shared_from_this 201603 66338fd1498Szrj weak_ptr<_Tp> 66438fd1498Szrj weak_from_this() noexcept 66538fd1498Szrj { return this->_M_weak_this; } 66638fd1498Szrj 66738fd1498Szrj weak_ptr<const _Tp> 66838fd1498Szrj weak_from_this() const noexcept 66938fd1498Szrj { return this->_M_weak_this; } 67038fd1498Szrj #endif 67138fd1498Szrj 67238fd1498Szrj private: 67338fd1498Szrj template<typename _Tp1> 67438fd1498Szrj void 67538fd1498Szrj _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept 67638fd1498Szrj { _M_weak_this._M_assign(__p, __n); } 67738fd1498Szrj 67838fd1498Szrj // Found by ADL when this is an associated class. 67938fd1498Szrj friend const enable_shared_from_this* 68038fd1498Szrj __enable_shared_from_this_base(const __shared_count<>&, 68138fd1498Szrj const enable_shared_from_this* __p) 68238fd1498Szrj { return __p; } 68338fd1498Szrj 68438fd1498Szrj template<typename, _Lock_policy> 68538fd1498Szrj friend class __shared_ptr; 68638fd1498Szrj 68738fd1498Szrj mutable weak_ptr<_Tp> _M_weak_this; 68838fd1498Szrj }; 68938fd1498Szrj 69038fd1498Szrj /** 69138fd1498Szrj * @brief Create an object that is owned by a shared_ptr. 69238fd1498Szrj * @param __a An allocator. 69338fd1498Szrj * @param __args Arguments for the @a _Tp object's constructor. 69438fd1498Szrj * @return A shared_ptr that owns the newly created object. 69538fd1498Szrj * @throw An exception thrown from @a _Alloc::allocate or from the 69638fd1498Szrj * constructor of @a _Tp. 69738fd1498Szrj * 69838fd1498Szrj * A copy of @a __a will be used to allocate memory for the shared_ptr 69938fd1498Szrj * and the new object. 70038fd1498Szrj */ 70138fd1498Szrj template<typename _Tp, typename _Alloc, typename... _Args> 70238fd1498Szrj inline shared_ptr<_Tp> 70338fd1498Szrj allocate_shared(const _Alloc& __a, _Args&&... __args) 70438fd1498Szrj { 705*58e805e6Szrj return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a}, 70638fd1498Szrj std::forward<_Args>(__args)...); 70738fd1498Szrj } 70838fd1498Szrj 70938fd1498Szrj /** 71038fd1498Szrj * @brief Create an object that is owned by a shared_ptr. 71138fd1498Szrj * @param __args Arguments for the @a _Tp object's constructor. 71238fd1498Szrj * @return A shared_ptr that owns the newly created object. 71338fd1498Szrj * @throw std::bad_alloc, or an exception thrown from the 71438fd1498Szrj * constructor of @a _Tp. 71538fd1498Szrj */ 71638fd1498Szrj template<typename _Tp, typename... _Args> 71738fd1498Szrj inline shared_ptr<_Tp> 71838fd1498Szrj make_shared(_Args&&... __args) 71938fd1498Szrj { 720*58e805e6Szrj typedef typename std::remove_cv<_Tp>::type _Tp_nc; 72138fd1498Szrj return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), 72238fd1498Szrj std::forward<_Args>(__args)...); 72338fd1498Szrj } 72438fd1498Szrj 72538fd1498Szrj /// std::hash specialization for shared_ptr. 72638fd1498Szrj template<typename _Tp> 72738fd1498Szrj struct hash<shared_ptr<_Tp>> 72838fd1498Szrj : public __hash_base<size_t, shared_ptr<_Tp>> 72938fd1498Szrj { 73038fd1498Szrj size_t 73138fd1498Szrj operator()(const shared_ptr<_Tp>& __s) const noexcept 73238fd1498Szrj { 73338fd1498Szrj return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get()); 73438fd1498Szrj } 73538fd1498Szrj }; 73638fd1498Szrj 73738fd1498Szrj // @} group pointer_abstractions 73838fd1498Szrj 73938fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 74038fd1498Szrj } // namespace 74138fd1498Szrj 74238fd1498Szrj #endif // _SHARED_PTR_H 743