1*38fd1498Szrj // shared_ptr and weak_ptr implementation -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2007-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj // GCC Note: Based on files from version 1.32.0 of the Boost library. 26*38fd1498Szrj 27*38fd1498Szrj // shared_count.hpp 28*38fd1498Szrj // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 29*38fd1498Szrj 30*38fd1498Szrj // shared_ptr.hpp 31*38fd1498Szrj // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. 32*38fd1498Szrj // Copyright (C) 2001, 2002, 2003 Peter Dimov 33*38fd1498Szrj 34*38fd1498Szrj // weak_ptr.hpp 35*38fd1498Szrj // Copyright (C) 2001, 2002, 2003 Peter Dimov 36*38fd1498Szrj 37*38fd1498Szrj // enable_shared_from_this.hpp 38*38fd1498Szrj // Copyright (C) 2002 Peter Dimov 39*38fd1498Szrj 40*38fd1498Szrj // Distributed under the Boost Software License, Version 1.0. (See 41*38fd1498Szrj // accompanying file LICENSE_1_0.txt or copy at 42*38fd1498Szrj // http://www.boost.org/LICENSE_1_0.txt) 43*38fd1498Szrj 44*38fd1498Szrj /** @file 45*38fd1498Szrj * This is an internal header file, included by other library headers. 46*38fd1498Szrj * Do not attempt to use it directly. @headername{memory} 47*38fd1498Szrj */ 48*38fd1498Szrj 49*38fd1498Szrj #ifndef _SHARED_PTR_H 50*38fd1498Szrj #define _SHARED_PTR_H 1 51*38fd1498Szrj 52*38fd1498Szrj #include <bits/shared_ptr_base.h> 53*38fd1498Szrj 54*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 55*38fd1498Szrj { 56*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 57*38fd1498Szrj 58*38fd1498Szrj /** 59*38fd1498Szrj * @addtogroup pointer_abstractions 60*38fd1498Szrj * @{ 61*38fd1498Szrj */ 62*38fd1498Szrj 63*38fd1498Szrj /// 20.7.2.2.11 shared_ptr I/O 64*38fd1498Szrj template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> 65*38fd1498Szrj inline std::basic_ostream<_Ch, _Tr>& 66*38fd1498Szrj operator<<(std::basic_ostream<_Ch, _Tr>& __os, 67*38fd1498Szrj const __shared_ptr<_Tp, _Lp>& __p) 68*38fd1498Szrj { 69*38fd1498Szrj __os << __p.get(); 70*38fd1498Szrj return __os; 71*38fd1498Szrj } 72*38fd1498Szrj 73*38fd1498Szrj template<typename _Del, typename _Tp, _Lock_policy _Lp> 74*38fd1498Szrj inline _Del* 75*38fd1498Szrj get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept 76*38fd1498Szrj { 77*38fd1498Szrj #if __cpp_rtti 78*38fd1498Szrj return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 79*38fd1498Szrj #else 80*38fd1498Szrj return 0; 81*38fd1498Szrj #endif 82*38fd1498Szrj } 83*38fd1498Szrj 84*38fd1498Szrj /// 20.7.2.2.10 shared_ptr get_deleter 85*38fd1498Szrj template<typename _Del, typename _Tp> 86*38fd1498Szrj inline _Del* 87*38fd1498Szrj get_deleter(const shared_ptr<_Tp>& __p) noexcept 88*38fd1498Szrj { 89*38fd1498Szrj #if __cpp_rtti 90*38fd1498Szrj return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); 91*38fd1498Szrj #else 92*38fd1498Szrj return 0; 93*38fd1498Szrj #endif 94*38fd1498Szrj } 95*38fd1498Szrj 96*38fd1498Szrj /** 97*38fd1498Szrj * @brief A smart pointer with reference-counted copy semantics. 98*38fd1498Szrj * 99*38fd1498Szrj * The object pointed to is deleted when the last shared_ptr pointing to 100*38fd1498Szrj * it is destroyed or reset. 101*38fd1498Szrj */ 102*38fd1498Szrj template<typename _Tp> 103*38fd1498Szrj class shared_ptr : public __shared_ptr<_Tp> 104*38fd1498Szrj { 105*38fd1498Szrj template<typename... _Args> 106*38fd1498Szrj using _Constructible = typename enable_if< 107*38fd1498Szrj is_constructible<__shared_ptr<_Tp>, _Args...>::value 108*38fd1498Szrj >::type; 109*38fd1498Szrj 110*38fd1498Szrj template<typename _Arg> 111*38fd1498Szrj using _Assignable = typename enable_if< 112*38fd1498Szrj is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr& 113*38fd1498Szrj >::type; 114*38fd1498Szrj 115*38fd1498Szrj public: 116*38fd1498Szrj 117*38fd1498Szrj using element_type = typename __shared_ptr<_Tp>::element_type; 118*38fd1498Szrj 119*38fd1498Szrj #if __cplusplus > 201402L 120*38fd1498Szrj # define __cpp_lib_shared_ptr_weak_type 201606 121*38fd1498Szrj using weak_type = weak_ptr<_Tp>; 122*38fd1498Szrj #endif 123*38fd1498Szrj /** 124*38fd1498Szrj * @brief Construct an empty %shared_ptr. 125*38fd1498Szrj * @post use_count()==0 && get()==0 126*38fd1498Szrj */ 127*38fd1498Szrj constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { } 128*38fd1498Szrj 129*38fd1498Szrj shared_ptr(const shared_ptr&) noexcept = default; 130*38fd1498Szrj 131*38fd1498Szrj /** 132*38fd1498Szrj * @brief Construct a %shared_ptr that owns the pointer @a __p. 133*38fd1498Szrj * @param __p A pointer that is convertible to element_type*. 134*38fd1498Szrj * @post use_count() == 1 && get() == __p 135*38fd1498Szrj * @throw std::bad_alloc, in which case @c delete @a __p is called. 136*38fd1498Szrj */ 137*38fd1498Szrj template<typename _Yp, typename = _Constructible<_Yp*>> 138*38fd1498Szrj explicit 139*38fd1498Szrj shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { } 140*38fd1498Szrj 141*38fd1498Szrj /** 142*38fd1498Szrj * @brief Construct a %shared_ptr that owns the pointer @a __p 143*38fd1498Szrj * and the deleter @a __d. 144*38fd1498Szrj * @param __p A pointer. 145*38fd1498Szrj * @param __d A deleter. 146*38fd1498Szrj * @post use_count() == 1 && get() == __p 147*38fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called. 148*38fd1498Szrj * 149*38fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must 150*38fd1498Szrj * not throw 151*38fd1498Szrj * 152*38fd1498Szrj * __shared_ptr will release __p by calling __d(__p) 153*38fd1498Szrj */ 154*38fd1498Szrj template<typename _Yp, typename _Deleter, 155*38fd1498Szrj typename = _Constructible<_Yp*, _Deleter>> 156*38fd1498Szrj shared_ptr(_Yp* __p, _Deleter __d) 157*38fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d)) { } 158*38fd1498Szrj 159*38fd1498Szrj /** 160*38fd1498Szrj * @brief Construct a %shared_ptr that owns a null pointer 161*38fd1498Szrj * and the deleter @a __d. 162*38fd1498Szrj * @param __p A null pointer constant. 163*38fd1498Szrj * @param __d A deleter. 164*38fd1498Szrj * @post use_count() == 1 && get() == __p 165*38fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called. 166*38fd1498Szrj * 167*38fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must 168*38fd1498Szrj * not throw 169*38fd1498Szrj * 170*38fd1498Szrj * The last owner will call __d(__p) 171*38fd1498Szrj */ 172*38fd1498Szrj template<typename _Deleter> 173*38fd1498Szrj shared_ptr(nullptr_t __p, _Deleter __d) 174*38fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d)) { } 175*38fd1498Szrj 176*38fd1498Szrj /** 177*38fd1498Szrj * @brief Construct a %shared_ptr that owns the pointer @a __p 178*38fd1498Szrj * and the deleter @a __d. 179*38fd1498Szrj * @param __p A pointer. 180*38fd1498Szrj * @param __d A deleter. 181*38fd1498Szrj * @param __a An allocator. 182*38fd1498Szrj * @post use_count() == 1 && get() == __p 183*38fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called. 184*38fd1498Szrj * 185*38fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must 186*38fd1498Szrj * not throw _Alloc's copy constructor and destructor must not 187*38fd1498Szrj * throw. 188*38fd1498Szrj * 189*38fd1498Szrj * __shared_ptr will release __p by calling __d(__p) 190*38fd1498Szrj */ 191*38fd1498Szrj template<typename _Yp, typename _Deleter, typename _Alloc, 192*38fd1498Szrj typename = _Constructible<_Yp*, _Deleter, _Alloc>> 193*38fd1498Szrj shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a) 194*38fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } 195*38fd1498Szrj 196*38fd1498Szrj /** 197*38fd1498Szrj * @brief Construct a %shared_ptr that owns a null pointer 198*38fd1498Szrj * and the deleter @a __d. 199*38fd1498Szrj * @param __p A null pointer constant. 200*38fd1498Szrj * @param __d A deleter. 201*38fd1498Szrj * @param __a An allocator. 202*38fd1498Szrj * @post use_count() == 1 && get() == __p 203*38fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called. 204*38fd1498Szrj * 205*38fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must 206*38fd1498Szrj * not throw _Alloc's copy constructor and destructor must not 207*38fd1498Szrj * throw. 208*38fd1498Szrj * 209*38fd1498Szrj * The last owner will call __d(__p) 210*38fd1498Szrj */ 211*38fd1498Szrj template<typename _Deleter, typename _Alloc> 212*38fd1498Szrj shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) 213*38fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { } 214*38fd1498Szrj 215*38fd1498Szrj // Aliasing constructor 216*38fd1498Szrj 217*38fd1498Szrj /** 218*38fd1498Szrj * @brief Constructs a %shared_ptr instance that stores @a __p 219*38fd1498Szrj * and shares ownership with @a __r. 220*38fd1498Szrj * @param __r A %shared_ptr. 221*38fd1498Szrj * @param __p A pointer that will remain valid while @a *__r is valid. 222*38fd1498Szrj * @post get() == __p && use_count() == __r.use_count() 223*38fd1498Szrj * 224*38fd1498Szrj * This can be used to construct a @c shared_ptr to a sub-object 225*38fd1498Szrj * of an object managed by an existing @c shared_ptr. 226*38fd1498Szrj * 227*38fd1498Szrj * @code 228*38fd1498Szrj * shared_ptr< pair<int,int> > pii(new pair<int,int>()); 229*38fd1498Szrj * shared_ptr<int> pi(pii, &pii->first); 230*38fd1498Szrj * assert(pii.use_count() == 2); 231*38fd1498Szrj * @endcode 232*38fd1498Szrj */ 233*38fd1498Szrj template<typename _Yp> 234*38fd1498Szrj shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept 235*38fd1498Szrj : __shared_ptr<_Tp>(__r, __p) { } 236*38fd1498Szrj 237*38fd1498Szrj /** 238*38fd1498Szrj * @brief If @a __r is empty, constructs an empty %shared_ptr; 239*38fd1498Szrj * otherwise construct a %shared_ptr that shares ownership 240*38fd1498Szrj * with @a __r. 241*38fd1498Szrj * @param __r A %shared_ptr. 242*38fd1498Szrj * @post get() == __r.get() && use_count() == __r.use_count() 243*38fd1498Szrj */ 244*38fd1498Szrj template<typename _Yp, 245*38fd1498Szrj typename = _Constructible<const shared_ptr<_Yp>&>> 246*38fd1498Szrj shared_ptr(const shared_ptr<_Yp>& __r) noexcept 247*38fd1498Szrj : __shared_ptr<_Tp>(__r) { } 248*38fd1498Szrj 249*38fd1498Szrj /** 250*38fd1498Szrj * @brief Move-constructs a %shared_ptr instance from @a __r. 251*38fd1498Szrj * @param __r A %shared_ptr rvalue. 252*38fd1498Szrj * @post *this contains the old value of @a __r, @a __r is empty. 253*38fd1498Szrj */ 254*38fd1498Szrj shared_ptr(shared_ptr&& __r) noexcept 255*38fd1498Szrj : __shared_ptr<_Tp>(std::move(__r)) { } 256*38fd1498Szrj 257*38fd1498Szrj /** 258*38fd1498Szrj * @brief Move-constructs a %shared_ptr instance from @a __r. 259*38fd1498Szrj * @param __r A %shared_ptr rvalue. 260*38fd1498Szrj * @post *this contains the old value of @a __r, @a __r is empty. 261*38fd1498Szrj */ 262*38fd1498Szrj template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>> 263*38fd1498Szrj shared_ptr(shared_ptr<_Yp>&& __r) noexcept 264*38fd1498Szrj : __shared_ptr<_Tp>(std::move(__r)) { } 265*38fd1498Szrj 266*38fd1498Szrj /** 267*38fd1498Szrj * @brief Constructs a %shared_ptr that shares ownership with @a __r 268*38fd1498Szrj * and stores a copy of the pointer stored in @a __r. 269*38fd1498Szrj * @param __r A weak_ptr. 270*38fd1498Szrj * @post use_count() == __r.use_count() 271*38fd1498Szrj * @throw bad_weak_ptr when __r.expired(), 272*38fd1498Szrj * in which case the constructor has no effect. 273*38fd1498Szrj */ 274*38fd1498Szrj template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> 275*38fd1498Szrj explicit shared_ptr(const weak_ptr<_Yp>& __r) 276*38fd1498Szrj : __shared_ptr<_Tp>(__r) { } 277*38fd1498Szrj 278*38fd1498Szrj #if _GLIBCXX_USE_DEPRECATED 279*38fd1498Szrj #pragma GCC diagnostic push 280*38fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 281*38fd1498Szrj template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>> 282*38fd1498Szrj shared_ptr(auto_ptr<_Yp>&& __r); 283*38fd1498Szrj #pragma GCC diagnostic pop 284*38fd1498Szrj #endif 285*38fd1498Szrj 286*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 287*38fd1498Szrj // 2399. shared_ptr's constructor from unique_ptr should be constrained 288*38fd1498Szrj template<typename _Yp, typename _Del, 289*38fd1498Szrj typename = _Constructible<unique_ptr<_Yp, _Del>>> 290*38fd1498Szrj shared_ptr(unique_ptr<_Yp, _Del>&& __r) 291*38fd1498Szrj : __shared_ptr<_Tp>(std::move(__r)) { } 292*38fd1498Szrj 293*38fd1498Szrj #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED 294*38fd1498Szrj // This non-standard constructor exists to support conversions that 295*38fd1498Szrj // were possible in C++11 and C++14 but are ill-formed in C++17. 296*38fd1498Szrj // If an exception is thrown this constructor has no effect. 297*38fd1498Szrj template<typename _Yp, typename _Del, 298*38fd1498Szrj _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0> 299*38fd1498Szrj shared_ptr(unique_ptr<_Yp, _Del>&& __r) 300*38fd1498Szrj : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { } 301*38fd1498Szrj #endif 302*38fd1498Szrj 303*38fd1498Szrj /** 304*38fd1498Szrj * @brief Construct an empty %shared_ptr. 305*38fd1498Szrj * @post use_count() == 0 && get() == nullptr 306*38fd1498Szrj */ 307*38fd1498Szrj constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { } 308*38fd1498Szrj 309*38fd1498Szrj shared_ptr& operator=(const shared_ptr&) noexcept = default; 310*38fd1498Szrj 311*38fd1498Szrj template<typename _Yp> 312*38fd1498Szrj _Assignable<const shared_ptr<_Yp>&> 313*38fd1498Szrj operator=(const shared_ptr<_Yp>& __r) noexcept 314*38fd1498Szrj { 315*38fd1498Szrj this->__shared_ptr<_Tp>::operator=(__r); 316*38fd1498Szrj return *this; 317*38fd1498Szrj } 318*38fd1498Szrj 319*38fd1498Szrj #if _GLIBCXX_USE_DEPRECATED 320*38fd1498Szrj #pragma GCC diagnostic push 321*38fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 322*38fd1498Szrj template<typename _Yp> 323*38fd1498Szrj _Assignable<auto_ptr<_Yp>> 324*38fd1498Szrj operator=(auto_ptr<_Yp>&& __r) 325*38fd1498Szrj { 326*38fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r)); 327*38fd1498Szrj return *this; 328*38fd1498Szrj } 329*38fd1498Szrj #pragma GCC diagnostic pop 330*38fd1498Szrj #endif 331*38fd1498Szrj 332*38fd1498Szrj shared_ptr& 333*38fd1498Szrj operator=(shared_ptr&& __r) noexcept 334*38fd1498Szrj { 335*38fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r)); 336*38fd1498Szrj return *this; 337*38fd1498Szrj } 338*38fd1498Szrj 339*38fd1498Szrj template<class _Yp> 340*38fd1498Szrj _Assignable<shared_ptr<_Yp>> 341*38fd1498Szrj operator=(shared_ptr<_Yp>&& __r) noexcept 342*38fd1498Szrj { 343*38fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r)); 344*38fd1498Szrj return *this; 345*38fd1498Szrj } 346*38fd1498Szrj 347*38fd1498Szrj template<typename _Yp, typename _Del> 348*38fd1498Szrj _Assignable<unique_ptr<_Yp, _Del>> 349*38fd1498Szrj operator=(unique_ptr<_Yp, _Del>&& __r) 350*38fd1498Szrj { 351*38fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r)); 352*38fd1498Szrj return *this; 353*38fd1498Szrj } 354*38fd1498Szrj 355*38fd1498Szrj private: 356*38fd1498Szrj // This constructor is non-standard, it is used by allocate_shared. 357*38fd1498Szrj template<typename _Alloc, typename... _Args> 358*38fd1498Szrj shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 359*38fd1498Szrj _Args&&... __args) 360*38fd1498Szrj : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...) 361*38fd1498Szrj { } 362*38fd1498Szrj 363*38fd1498Szrj template<typename _Yp, typename _Alloc, typename... _Args> 364*38fd1498Szrj friend shared_ptr<_Yp> 365*38fd1498Szrj allocate_shared(const _Alloc& __a, _Args&&... __args); 366*38fd1498Szrj 367*38fd1498Szrj // This constructor is non-standard, it is used by weak_ptr::lock(). 368*38fd1498Szrj shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) 369*38fd1498Szrj : __shared_ptr<_Tp>(__r, std::nothrow) { } 370*38fd1498Szrj 371*38fd1498Szrj friend class weak_ptr<_Tp>; 372*38fd1498Szrj }; 373*38fd1498Szrj 374*38fd1498Szrj #if __cpp_deduction_guides >= 201606 375*38fd1498Szrj template<typename _Tp> 376*38fd1498Szrj shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; 377*38fd1498Szrj template<typename _Tp, typename _Del> 378*38fd1498Szrj shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>; 379*38fd1498Szrj #endif 380*38fd1498Szrj 381*38fd1498Szrj // 20.7.2.2.7 shared_ptr comparisons 382*38fd1498Szrj template<typename _Tp, typename _Up> 383*38fd1498Szrj inline bool 384*38fd1498Szrj operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 385*38fd1498Szrj { return __a.get() == __b.get(); } 386*38fd1498Szrj 387*38fd1498Szrj template<typename _Tp> 388*38fd1498Szrj inline bool 389*38fd1498Szrj operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 390*38fd1498Szrj { return !__a; } 391*38fd1498Szrj 392*38fd1498Szrj template<typename _Tp> 393*38fd1498Szrj inline bool 394*38fd1498Szrj operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 395*38fd1498Szrj { return !__a; } 396*38fd1498Szrj 397*38fd1498Szrj template<typename _Tp, typename _Up> 398*38fd1498Szrj inline bool 399*38fd1498Szrj operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 400*38fd1498Szrj { return __a.get() != __b.get(); } 401*38fd1498Szrj 402*38fd1498Szrj template<typename _Tp> 403*38fd1498Szrj inline bool 404*38fd1498Szrj operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 405*38fd1498Szrj { return (bool)__a; } 406*38fd1498Szrj 407*38fd1498Szrj template<typename _Tp> 408*38fd1498Szrj inline bool 409*38fd1498Szrj operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 410*38fd1498Szrj { return (bool)__a; } 411*38fd1498Szrj 412*38fd1498Szrj template<typename _Tp, typename _Up> 413*38fd1498Szrj inline bool 414*38fd1498Szrj operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 415*38fd1498Szrj { 416*38fd1498Szrj using _Tp_elt = typename shared_ptr<_Tp>::element_type; 417*38fd1498Szrj using _Up_elt = typename shared_ptr<_Up>::element_type; 418*38fd1498Szrj using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type; 419*38fd1498Szrj return less<_Vp>()(__a.get(), __b.get()); 420*38fd1498Szrj } 421*38fd1498Szrj 422*38fd1498Szrj template<typename _Tp> 423*38fd1498Szrj inline bool 424*38fd1498Szrj operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 425*38fd1498Szrj { 426*38fd1498Szrj using _Tp_elt = typename shared_ptr<_Tp>::element_type; 427*38fd1498Szrj return less<_Tp_elt*>()(__a.get(), nullptr); 428*38fd1498Szrj } 429*38fd1498Szrj 430*38fd1498Szrj template<typename _Tp> 431*38fd1498Szrj inline bool 432*38fd1498Szrj operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 433*38fd1498Szrj { 434*38fd1498Szrj using _Tp_elt = typename shared_ptr<_Tp>::element_type; 435*38fd1498Szrj return less<_Tp_elt*>()(nullptr, __a.get()); 436*38fd1498Szrj } 437*38fd1498Szrj 438*38fd1498Szrj template<typename _Tp, typename _Up> 439*38fd1498Szrj inline bool 440*38fd1498Szrj operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 441*38fd1498Szrj { return !(__b < __a); } 442*38fd1498Szrj 443*38fd1498Szrj template<typename _Tp> 444*38fd1498Szrj inline bool 445*38fd1498Szrj operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 446*38fd1498Szrj { return !(nullptr < __a); } 447*38fd1498Szrj 448*38fd1498Szrj template<typename _Tp> 449*38fd1498Szrj inline bool 450*38fd1498Szrj operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 451*38fd1498Szrj { return !(__a < nullptr); } 452*38fd1498Szrj 453*38fd1498Szrj template<typename _Tp, typename _Up> 454*38fd1498Szrj inline bool 455*38fd1498Szrj operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 456*38fd1498Szrj { return (__b < __a); } 457*38fd1498Szrj 458*38fd1498Szrj template<typename _Tp> 459*38fd1498Szrj inline bool 460*38fd1498Szrj operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 461*38fd1498Szrj { return nullptr < __a; } 462*38fd1498Szrj 463*38fd1498Szrj template<typename _Tp> 464*38fd1498Szrj inline bool 465*38fd1498Szrj operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 466*38fd1498Szrj { return __a < nullptr; } 467*38fd1498Szrj 468*38fd1498Szrj template<typename _Tp, typename _Up> 469*38fd1498Szrj inline bool 470*38fd1498Szrj operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept 471*38fd1498Szrj { return !(__a < __b); } 472*38fd1498Szrj 473*38fd1498Szrj template<typename _Tp> 474*38fd1498Szrj inline bool 475*38fd1498Szrj operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept 476*38fd1498Szrj { return !(__a < nullptr); } 477*38fd1498Szrj 478*38fd1498Szrj template<typename _Tp> 479*38fd1498Szrj inline bool 480*38fd1498Szrj operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept 481*38fd1498Szrj { return !(nullptr < __a); } 482*38fd1498Szrj 483*38fd1498Szrj template<typename _Tp> 484*38fd1498Szrj struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> 485*38fd1498Szrj { }; 486*38fd1498Szrj 487*38fd1498Szrj // 20.7.2.2.8 shared_ptr specialized algorithms. 488*38fd1498Szrj template<typename _Tp> 489*38fd1498Szrj inline void 490*38fd1498Szrj swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept 491*38fd1498Szrj { __a.swap(__b); } 492*38fd1498Szrj 493*38fd1498Szrj // 20.7.2.2.9 shared_ptr casts. 494*38fd1498Szrj template<typename _Tp, typename _Up> 495*38fd1498Szrj inline shared_ptr<_Tp> 496*38fd1498Szrj static_pointer_cast(const shared_ptr<_Up>& __r) noexcept 497*38fd1498Szrj { 498*38fd1498Szrj using _Sp = shared_ptr<_Tp>; 499*38fd1498Szrj return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get())); 500*38fd1498Szrj } 501*38fd1498Szrj 502*38fd1498Szrj template<typename _Tp, typename _Up> 503*38fd1498Szrj inline shared_ptr<_Tp> 504*38fd1498Szrj const_pointer_cast(const shared_ptr<_Up>& __r) noexcept 505*38fd1498Szrj { 506*38fd1498Szrj using _Sp = shared_ptr<_Tp>; 507*38fd1498Szrj return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get())); 508*38fd1498Szrj } 509*38fd1498Szrj 510*38fd1498Szrj template<typename _Tp, typename _Up> 511*38fd1498Szrj inline shared_ptr<_Tp> 512*38fd1498Szrj dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept 513*38fd1498Szrj { 514*38fd1498Szrj using _Sp = shared_ptr<_Tp>; 515*38fd1498Szrj if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get())) 516*38fd1498Szrj return _Sp(__r, __p); 517*38fd1498Szrj return _Sp(); 518*38fd1498Szrj } 519*38fd1498Szrj 520*38fd1498Szrj #if __cplusplus > 201402L 521*38fd1498Szrj template<typename _Tp, typename _Up> 522*38fd1498Szrj inline shared_ptr<_Tp> 523*38fd1498Szrj reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept 524*38fd1498Szrj { 525*38fd1498Szrj using _Sp = shared_ptr<_Tp>; 526*38fd1498Szrj return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get())); 527*38fd1498Szrj } 528*38fd1498Szrj #endif 529*38fd1498Szrj 530*38fd1498Szrj /** 531*38fd1498Szrj * @brief A smart pointer with weak semantics. 532*38fd1498Szrj * 533*38fd1498Szrj * With forwarding constructors and assignment operators. 534*38fd1498Szrj */ 535*38fd1498Szrj template<typename _Tp> 536*38fd1498Szrj class weak_ptr : public __weak_ptr<_Tp> 537*38fd1498Szrj { 538*38fd1498Szrj template<typename _Arg> 539*38fd1498Szrj using _Constructible = typename enable_if< 540*38fd1498Szrj is_constructible<__weak_ptr<_Tp>, _Arg>::value 541*38fd1498Szrj >::type; 542*38fd1498Szrj 543*38fd1498Szrj template<typename _Arg> 544*38fd1498Szrj using _Assignable = typename enable_if< 545*38fd1498Szrj is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr& 546*38fd1498Szrj >::type; 547*38fd1498Szrj 548*38fd1498Szrj public: 549*38fd1498Szrj constexpr weak_ptr() noexcept = default; 550*38fd1498Szrj 551*38fd1498Szrj template<typename _Yp, 552*38fd1498Szrj typename = _Constructible<const shared_ptr<_Yp>&>> 553*38fd1498Szrj weak_ptr(const shared_ptr<_Yp>& __r) noexcept 554*38fd1498Szrj : __weak_ptr<_Tp>(__r) { } 555*38fd1498Szrj 556*38fd1498Szrj weak_ptr(const weak_ptr&) noexcept = default; 557*38fd1498Szrj 558*38fd1498Szrj template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>> 559*38fd1498Szrj weak_ptr(const weak_ptr<_Yp>& __r) noexcept 560*38fd1498Szrj : __weak_ptr<_Tp>(__r) { } 561*38fd1498Szrj 562*38fd1498Szrj weak_ptr(weak_ptr&&) noexcept = default; 563*38fd1498Szrj 564*38fd1498Szrj template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>> 565*38fd1498Szrj weak_ptr(weak_ptr<_Yp>&& __r) noexcept 566*38fd1498Szrj : __weak_ptr<_Tp>(std::move(__r)) { } 567*38fd1498Szrj 568*38fd1498Szrj weak_ptr& 569*38fd1498Szrj operator=(const weak_ptr& __r) noexcept = default; 570*38fd1498Szrj 571*38fd1498Szrj template<typename _Yp> 572*38fd1498Szrj _Assignable<const weak_ptr<_Yp>&> 573*38fd1498Szrj operator=(const weak_ptr<_Yp>& __r) noexcept 574*38fd1498Szrj { 575*38fd1498Szrj this->__weak_ptr<_Tp>::operator=(__r); 576*38fd1498Szrj return *this; 577*38fd1498Szrj } 578*38fd1498Szrj 579*38fd1498Szrj template<typename _Yp> 580*38fd1498Szrj _Assignable<const shared_ptr<_Yp>&> 581*38fd1498Szrj operator=(const shared_ptr<_Yp>& __r) noexcept 582*38fd1498Szrj { 583*38fd1498Szrj this->__weak_ptr<_Tp>::operator=(__r); 584*38fd1498Szrj return *this; 585*38fd1498Szrj } 586*38fd1498Szrj 587*38fd1498Szrj weak_ptr& 588*38fd1498Szrj operator=(weak_ptr&& __r) noexcept = default; 589*38fd1498Szrj 590*38fd1498Szrj template<typename _Yp> 591*38fd1498Szrj _Assignable<weak_ptr<_Yp>> 592*38fd1498Szrj operator=(weak_ptr<_Yp>&& __r) noexcept 593*38fd1498Szrj { 594*38fd1498Szrj this->__weak_ptr<_Tp>::operator=(std::move(__r)); 595*38fd1498Szrj return *this; 596*38fd1498Szrj } 597*38fd1498Szrj 598*38fd1498Szrj shared_ptr<_Tp> 599*38fd1498Szrj lock() const noexcept 600*38fd1498Szrj { return shared_ptr<_Tp>(*this, std::nothrow); } 601*38fd1498Szrj }; 602*38fd1498Szrj 603*38fd1498Szrj #if __cpp_deduction_guides >= 201606 604*38fd1498Szrj template<typename _Tp> 605*38fd1498Szrj weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; 606*38fd1498Szrj #endif 607*38fd1498Szrj 608*38fd1498Szrj // 20.7.2.3.6 weak_ptr specialized algorithms. 609*38fd1498Szrj template<typename _Tp> 610*38fd1498Szrj inline void 611*38fd1498Szrj swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept 612*38fd1498Szrj { __a.swap(__b); } 613*38fd1498Szrj 614*38fd1498Szrj 615*38fd1498Szrj /// Primary template owner_less 616*38fd1498Szrj template<typename _Tp = void> 617*38fd1498Szrj struct owner_less; 618*38fd1498Szrj 619*38fd1498Szrj /// Void specialization of owner_less 620*38fd1498Szrj template<> 621*38fd1498Szrj struct owner_less<void> : _Sp_owner_less<void, void> 622*38fd1498Szrj { }; 623*38fd1498Szrj 624*38fd1498Szrj /// Partial specialization of owner_less for shared_ptr. 625*38fd1498Szrj template<typename _Tp> 626*38fd1498Szrj struct owner_less<shared_ptr<_Tp>> 627*38fd1498Szrj : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> 628*38fd1498Szrj { }; 629*38fd1498Szrj 630*38fd1498Szrj /// Partial specialization of owner_less for weak_ptr. 631*38fd1498Szrj template<typename _Tp> 632*38fd1498Szrj struct owner_less<weak_ptr<_Tp>> 633*38fd1498Szrj : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> 634*38fd1498Szrj { }; 635*38fd1498Szrj 636*38fd1498Szrj /** 637*38fd1498Szrj * @brief Base class allowing use of member function shared_from_this. 638*38fd1498Szrj */ 639*38fd1498Szrj template<typename _Tp> 640*38fd1498Szrj class enable_shared_from_this 641*38fd1498Szrj { 642*38fd1498Szrj protected: 643*38fd1498Szrj constexpr enable_shared_from_this() noexcept { } 644*38fd1498Szrj 645*38fd1498Szrj enable_shared_from_this(const enable_shared_from_this&) noexcept { } 646*38fd1498Szrj 647*38fd1498Szrj enable_shared_from_this& 648*38fd1498Szrj operator=(const enable_shared_from_this&) noexcept 649*38fd1498Szrj { return *this; } 650*38fd1498Szrj 651*38fd1498Szrj ~enable_shared_from_this() { } 652*38fd1498Szrj 653*38fd1498Szrj public: 654*38fd1498Szrj shared_ptr<_Tp> 655*38fd1498Szrj shared_from_this() 656*38fd1498Szrj { return shared_ptr<_Tp>(this->_M_weak_this); } 657*38fd1498Szrj 658*38fd1498Szrj shared_ptr<const _Tp> 659*38fd1498Szrj shared_from_this() const 660*38fd1498Szrj { return shared_ptr<const _Tp>(this->_M_weak_this); } 661*38fd1498Szrj 662*38fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 663*38fd1498Szrj #define __cpp_lib_enable_shared_from_this 201603 664*38fd1498Szrj weak_ptr<_Tp> 665*38fd1498Szrj weak_from_this() noexcept 666*38fd1498Szrj { return this->_M_weak_this; } 667*38fd1498Szrj 668*38fd1498Szrj weak_ptr<const _Tp> 669*38fd1498Szrj weak_from_this() const noexcept 670*38fd1498Szrj { return this->_M_weak_this; } 671*38fd1498Szrj #endif 672*38fd1498Szrj 673*38fd1498Szrj private: 674*38fd1498Szrj template<typename _Tp1> 675*38fd1498Szrj void 676*38fd1498Szrj _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept 677*38fd1498Szrj { _M_weak_this._M_assign(__p, __n); } 678*38fd1498Szrj 679*38fd1498Szrj // Found by ADL when this is an associated class. 680*38fd1498Szrj friend const enable_shared_from_this* 681*38fd1498Szrj __enable_shared_from_this_base(const __shared_count<>&, 682*38fd1498Szrj const enable_shared_from_this* __p) 683*38fd1498Szrj { return __p; } 684*38fd1498Szrj 685*38fd1498Szrj template<typename, _Lock_policy> 686*38fd1498Szrj friend class __shared_ptr; 687*38fd1498Szrj 688*38fd1498Szrj mutable weak_ptr<_Tp> _M_weak_this; 689*38fd1498Szrj }; 690*38fd1498Szrj 691*38fd1498Szrj /** 692*38fd1498Szrj * @brief Create an object that is owned by a shared_ptr. 693*38fd1498Szrj * @param __a An allocator. 694*38fd1498Szrj * @param __args Arguments for the @a _Tp object's constructor. 695*38fd1498Szrj * @return A shared_ptr that owns the newly created object. 696*38fd1498Szrj * @throw An exception thrown from @a _Alloc::allocate or from the 697*38fd1498Szrj * constructor of @a _Tp. 698*38fd1498Szrj * 699*38fd1498Szrj * A copy of @a __a will be used to allocate memory for the shared_ptr 700*38fd1498Szrj * and the new object. 701*38fd1498Szrj */ 702*38fd1498Szrj template<typename _Tp, typename _Alloc, typename... _Args> 703*38fd1498Szrj inline shared_ptr<_Tp> 704*38fd1498Szrj allocate_shared(const _Alloc& __a, _Args&&... __args) 705*38fd1498Szrj { 706*38fd1498Szrj return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a, 707*38fd1498Szrj std::forward<_Args>(__args)...); 708*38fd1498Szrj } 709*38fd1498Szrj 710*38fd1498Szrj /** 711*38fd1498Szrj * @brief Create an object that is owned by a shared_ptr. 712*38fd1498Szrj * @param __args Arguments for the @a _Tp object's constructor. 713*38fd1498Szrj * @return A shared_ptr that owns the newly created object. 714*38fd1498Szrj * @throw std::bad_alloc, or an exception thrown from the 715*38fd1498Szrj * constructor of @a _Tp. 716*38fd1498Szrj */ 717*38fd1498Szrj template<typename _Tp, typename... _Args> 718*38fd1498Szrj inline shared_ptr<_Tp> 719*38fd1498Szrj make_shared(_Args&&... __args) 720*38fd1498Szrj { 721*38fd1498Szrj typedef typename std::remove_const<_Tp>::type _Tp_nc; 722*38fd1498Szrj return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(), 723*38fd1498Szrj std::forward<_Args>(__args)...); 724*38fd1498Szrj } 725*38fd1498Szrj 726*38fd1498Szrj /// std::hash specialization for shared_ptr. 727*38fd1498Szrj template<typename _Tp> 728*38fd1498Szrj struct hash<shared_ptr<_Tp>> 729*38fd1498Szrj : public __hash_base<size_t, shared_ptr<_Tp>> 730*38fd1498Szrj { 731*38fd1498Szrj size_t 732*38fd1498Szrj operator()(const shared_ptr<_Tp>& __s) const noexcept 733*38fd1498Szrj { 734*38fd1498Szrj return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get()); 735*38fd1498Szrj } 736*38fd1498Szrj }; 737*38fd1498Szrj 738*38fd1498Szrj // @} group pointer_abstractions 739*38fd1498Szrj 740*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 741*38fd1498Szrj } // namespace 742*38fd1498Szrj 743*38fd1498Szrj #endif // _SHARED_PTR_H 744