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