1169691Skan// <tr1/boost_shared_ptr.h> -*- C++ -*- 2169691Skan 3169691Skan// Copyright (C) 2005, 2006 Free Software Foundation, Inc. 4169691Skan// 5169691Skan// This file is part of the GNU ISO C++ Library. This library is free 6169691Skan// software; you can redistribute it and/or modify it under the 7169691Skan// terms of the GNU General Public License as published by the 8169691Skan// Free Software Foundation; either version 2, or (at your option) 9169691Skan// any later version. 10169691Skan 11169691Skan// This library is distributed in the hope that it will be useful, 12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of 13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14169691Skan// GNU General Public License for more details. 15169691Skan 16169691Skan// You should have received a copy of the GNU General Public License along 17169691Skan// with this library; see the file COPYING. If not, write to the Free 18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19169691Skan// USA. 20169691Skan 21169691Skan// As a special exception, you may use this file as part of a free software 22169691Skan// library without restriction. Specifically, if other files instantiate 23169691Skan// templates or use macros or inline functions from this file, or you compile 24169691Skan// this file and link it with other files to produce an executable, this 25169691Skan// file does not by itself cause the resulting executable to be covered by 26169691Skan// the GNU General Public License. This exception does not however 27169691Skan// invalidate any other reasons why the executable file might be covered by 28169691Skan// the GNU General Public License. 29169691Skan 30169691Skan// shared_count.hpp 31169691Skan// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 32169691Skan 33169691Skan// shared_ptr.hpp 34169691Skan// Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. 35169691Skan// Copyright (C) 2001, 2002, 2003 Peter Dimov 36169691Skan 37169691Skan// weak_ptr.hpp 38169691Skan// Copyright (C) 2001, 2002, 2003 Peter Dimov 39169691Skan 40169691Skan// enable_shared_from_this.hpp 41169691Skan// Copyright (C) 2002 Peter Dimov 42169691Skan 43169691Skan// Distributed under the Boost Software License, Version 1.0. (See 44169691Skan// accompanying file LICENSE_1_0.txt or copy at 45169691Skan// http://www.boost.org/LICENSE_1_0.txt) 46169691Skan 47169691Skan// GCC Note: based on version 1.32.0 of the Boost library. 48169691Skan 49169691Skan/** @file tr1/boost_shared_ptr.h 50169691Skan * This is an internal header file, included by other library headers. 51169691Skan * You should not attempt to use it directly. 52169691Skan */ 53169691Skan 54169691Skan#ifndef _BOOST_SHARED_PTR_H 55169691Skan#define _BOOST_SHARED_PTR_H 1 56169691Skan 57169691Skannamespace std 58169691Skan{ 59169691Skan_GLIBCXX_BEGIN_NAMESPACE(tr1) 60169691Skan 61169691Skan class bad_weak_ptr : public std::exception 62169691Skan { 63169691Skan public: 64169691Skan virtual char const* 65169691Skan what() const throw() 66169691Skan { return "tr1::bad_weak_ptr"; } 67169691Skan }; 68169691Skan 69169691Skan // Substitute for bad_weak_ptr object in the case of -fno-exceptions. 70169691Skan inline void 71169691Skan __throw_bad_weak_ptr() 72169691Skan { 73169691Skan#if __EXCEPTIONS 74169691Skan throw bad_weak_ptr(); 75169691Skan#else 76169691Skan std::abort(); 77169691Skan#endif 78169691Skan } 79169691Skan 80169691Skan using __gnu_cxx::_Lock_policy; 81169691Skan using __gnu_cxx::__default_lock_policy; 82169691Skan using __gnu_cxx::_S_single; 83169691Skan using __gnu_cxx::_S_mutex; 84169691Skan using __gnu_cxx::_S_atomic; 85169691Skan 86169691Skan template<typename _Tp> 87169691Skan struct _Sp_deleter 88169691Skan { 89169691Skan typedef void result_type; 90169691Skan typedef _Tp* argument_type; 91169691Skan 92169691Skan void 93169691Skan operator()(_Tp* __p) const 94169691Skan { delete __p; } 95169691Skan }; 96169691Skan 97169691Skan // Empty helper class except when the template argument is _S_mutex. 98169691Skan template<_Lock_policy _Lp> 99169691Skan class _Mutex_base 100169691Skan { }; 101169691Skan 102169691Skan template<> 103169691Skan class _Mutex_base<_S_mutex> 104169691Skan : public __gnu_cxx::__mutex 105169691Skan { }; 106169691Skan 107169691Skan template<_Lock_policy _Lp = __default_lock_policy> 108169691Skan class _Sp_counted_base 109169691Skan : public _Mutex_base<_Lp> 110169691Skan { 111169691Skan public: 112169691Skan _Sp_counted_base() 113169691Skan : _M_use_count(1), _M_weak_count(1) { } 114169691Skan 115169691Skan virtual 116169691Skan ~_Sp_counted_base() // nothrow 117169691Skan { } 118169691Skan 119169691Skan // Called when _M_use_count drops to zero, to release the resources 120169691Skan // managed by *this. 121169691Skan virtual void 122169691Skan _M_dispose() = 0; // nothrow 123169691Skan 124169691Skan // Called when _M_weak_count drops to zero. 125169691Skan virtual void 126169691Skan _M_destroy() // nothrow 127169691Skan { delete this; } 128169691Skan 129169691Skan virtual void* 130169691Skan _M_get_deleter(const std::type_info&) = 0; 131169691Skan 132169691Skan void 133169691Skan _M_add_ref_copy() 134169691Skan { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); } 135169691Skan 136169691Skan void 137169691Skan _M_add_ref_lock(); 138169691Skan 139169691Skan void 140169691Skan _M_release() // nothrow 141169691Skan { 142169691Skan if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 143169691Skan -1) == 1) 144169691Skan { 145169691Skan _M_dispose(); 146169691Skan#ifdef __GTHREADS 147169691Skan _GLIBCXX_READ_MEM_BARRIER; 148169691Skan _GLIBCXX_WRITE_MEM_BARRIER; 149169691Skan#endif 150169691Skan if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, 151169691Skan -1) == 1) 152169691Skan _M_destroy(); 153169691Skan } 154169691Skan } 155169691Skan 156169691Skan void 157169691Skan _M_weak_add_ref() // nothrow 158169691Skan { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); } 159169691Skan 160169691Skan void 161169691Skan _M_weak_release() // nothrow 162169691Skan { 163169691Skan if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1) 164169691Skan { 165169691Skan#ifdef __GTHREADS 166169691Skan _GLIBCXX_READ_MEM_BARRIER; 167169691Skan _GLIBCXX_WRITE_MEM_BARRIER; 168169691Skan#endif 169169691Skan _M_destroy(); 170169691Skan } 171169691Skan } 172169691Skan 173169691Skan long 174169691Skan _M_get_use_count() const // nothrow 175169691Skan { return _M_use_count; } // XXX is this MT safe? 176169691Skan 177169691Skan private: 178169691Skan _Sp_counted_base(_Sp_counted_base const&); 179169691Skan _Sp_counted_base& operator=(_Sp_counted_base const&); 180169691Skan 181169691Skan _Atomic_word _M_use_count; // #shared 182169691Skan _Atomic_word _M_weak_count; // #weak + (#shared != 0) 183169691Skan }; 184169691Skan 185169691Skan template<> 186169691Skan inline void 187169691Skan _Sp_counted_base<_S_single>:: 188169691Skan _M_add_ref_lock() 189169691Skan { 190169691Skan if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 191169691Skan { 192169691Skan _M_use_count = 0; 193169691Skan __throw_bad_weak_ptr(); 194169691Skan } 195169691Skan } 196169691Skan 197169691Skan#ifdef __GTHREADS 198169691Skan template<> 199169691Skan inline void 200169691Skan _Sp_counted_base<_S_mutex>:: 201169691Skan _M_add_ref_lock() 202169691Skan { 203169691Skan __gnu_cxx::__scoped_lock sentry(*this); 204169691Skan if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) 205169691Skan { 206169691Skan _M_use_count = 0; 207169691Skan __throw_bad_weak_ptr(); 208169691Skan } 209169691Skan } 210169691Skan#endif 211169691Skan 212169691Skan template<> 213169691Skan inline void 214169691Skan _Sp_counted_base<_S_atomic>:: 215169691Skan _M_add_ref_lock() 216169691Skan { 217169691Skan // Perform lock-free add-if-not-zero operation. 218169691Skan _Atomic_word __count; 219169691Skan do 220169691Skan { 221169691Skan __count = _M_use_count; 222169691Skan if (__count == 0) 223169691Skan __throw_bad_weak_ptr(); 224169691Skan 225169691Skan // Replace the current counter value with the old value + 1, as 226169691Skan // long as it's not changed meanwhile. 227169691Skan } 228169691Skan while (!__sync_bool_compare_and_swap(&_M_use_count, __count, 229169691Skan __count + 1)); 230169691Skan } 231169691Skan 232169691Skan template<typename _Ptr, typename _Deleter, _Lock_policy _Lp> 233169691Skan class _Sp_counted_base_impl 234169691Skan : public _Sp_counted_base<_Lp> 235169691Skan { 236169691Skan public: 237169691Skan /** 238169691Skan * @brief 239169691Skan * @pre __d(__p) must not throw. 240169691Skan */ 241169691Skan _Sp_counted_base_impl(_Ptr __p, _Deleter __d) 242169691Skan : _M_ptr(__p), _M_del(__d) { } 243169691Skan 244169691Skan virtual void 245169691Skan _M_dispose() // nothrow 246169691Skan { _M_del(_M_ptr); } 247169691Skan 248169691Skan virtual void* 249169691Skan _M_get_deleter(const std::type_info& __ti) 250169691Skan { return __ti == typeid(_Deleter) ? &_M_del : 0; } 251169691Skan 252169691Skan private: 253169691Skan _Sp_counted_base_impl(const _Sp_counted_base_impl&); 254169691Skan _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&); 255169691Skan 256169691Skan _Ptr _M_ptr; // copy constructor must not throw 257169691Skan _Deleter _M_del; // copy constructor must not throw 258169691Skan }; 259169691Skan 260169691Skan template<_Lock_policy _Lp = __default_lock_policy> 261169691Skan class __weak_count; 262169691Skan 263169691Skan template<_Lock_policy _Lp = __default_lock_policy> 264169691Skan class __shared_count 265169691Skan { 266169691Skan public: 267169691Skan __shared_count() 268169691Skan : _M_pi(0) // nothrow 269169691Skan { } 270169691Skan 271169691Skan template<typename _Ptr, typename _Deleter> 272169691Skan __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0) 273169691Skan { 274169691Skan try 275169691Skan { 276169691Skan _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d); 277169691Skan } 278169691Skan catch(...) 279169691Skan { 280169691Skan __d(__p); // Call _Deleter on __p. 281169691Skan __throw_exception_again; 282169691Skan } 283169691Skan } 284169691Skan 285169691Skan // Special case for auto_ptr<_Tp> to provide the strong guarantee. 286169691Skan template<typename _Tp> 287169691Skan explicit 288169691Skan __shared_count(std::auto_ptr<_Tp>& __r) 289169691Skan : _M_pi(new _Sp_counted_base_impl<_Tp*, 290169691Skan _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>())) 291169691Skan { __r.release(); } 292169691Skan 293169691Skan // Throw bad_weak_ptr when __r._M_get_use_count() == 0. 294169691Skan explicit 295169691Skan __shared_count(const __weak_count<_Lp>& __r); 296169691Skan 297169691Skan ~__shared_count() // nothrow 298169691Skan { 299169691Skan if (_M_pi != 0) 300169691Skan _M_pi->_M_release(); 301169691Skan } 302169691Skan 303169691Skan __shared_count(const __shared_count& __r) 304169691Skan : _M_pi(__r._M_pi) // nothrow 305169691Skan { 306169691Skan if (_M_pi != 0) 307169691Skan _M_pi->_M_add_ref_copy(); 308169691Skan } 309169691Skan 310169691Skan __shared_count& 311169691Skan operator=(const __shared_count& __r) // nothrow 312169691Skan { 313169691Skan _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 314169691Skan if (__tmp != _M_pi) 315169691Skan { 316169691Skan if (__tmp != 0) 317169691Skan __tmp->_M_add_ref_copy(); 318169691Skan if (_M_pi != 0) 319169691Skan _M_pi->_M_release(); 320169691Skan _M_pi = __tmp; 321169691Skan } 322169691Skan return *this; 323169691Skan } 324169691Skan 325169691Skan void 326169691Skan _M_swap(__shared_count& __r) // nothrow 327169691Skan { 328169691Skan _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 329169691Skan __r._M_pi = _M_pi; 330169691Skan _M_pi = __tmp; 331169691Skan } 332169691Skan 333169691Skan long 334169691Skan _M_get_use_count() const // nothrow 335169691Skan { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 336169691Skan 337169691Skan bool 338169691Skan _M_unique() const // nothrow 339169691Skan { return this->_M_get_use_count() == 1; } 340169691Skan 341169691Skan friend inline bool 342169691Skan operator==(const __shared_count& __a, const __shared_count& __b) 343169691Skan { return __a._M_pi == __b._M_pi; } 344169691Skan 345169691Skan friend inline bool 346169691Skan operator<(const __shared_count& __a, const __shared_count& __b) 347169691Skan { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } 348169691Skan 349169691Skan void* 350169691Skan _M_get_deleter(const std::type_info& __ti) const 351169691Skan { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; } 352169691Skan 353169691Skan private: 354169691Skan friend class __weak_count<_Lp>; 355169691Skan 356169691Skan _Sp_counted_base<_Lp>* _M_pi; 357169691Skan }; 358169691Skan 359169691Skan template<_Lock_policy _Lp> 360169691Skan class __weak_count 361169691Skan { 362169691Skan public: 363169691Skan __weak_count() 364169691Skan : _M_pi(0) // nothrow 365169691Skan { } 366169691Skan 367169691Skan __weak_count(const __shared_count<_Lp>& __r) 368169691Skan : _M_pi(__r._M_pi) // nothrow 369169691Skan { 370169691Skan if (_M_pi != 0) 371169691Skan _M_pi->_M_weak_add_ref(); 372169691Skan } 373169691Skan 374169691Skan __weak_count(const __weak_count<_Lp>& __r) 375169691Skan : _M_pi(__r._M_pi) // nothrow 376169691Skan { 377169691Skan if (_M_pi != 0) 378169691Skan _M_pi->_M_weak_add_ref(); 379169691Skan } 380169691Skan 381169691Skan ~__weak_count() // nothrow 382169691Skan { 383169691Skan if (_M_pi != 0) 384169691Skan _M_pi->_M_weak_release(); 385169691Skan } 386169691Skan 387169691Skan __weak_count<_Lp>& 388169691Skan operator=(const __shared_count<_Lp>& __r) // nothrow 389169691Skan { 390169691Skan _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 391169691Skan if (__tmp != 0) 392169691Skan __tmp->_M_weak_add_ref(); 393169691Skan if (_M_pi != 0) 394169691Skan _M_pi->_M_weak_release(); 395169691Skan _M_pi = __tmp; 396169691Skan return *this; 397169691Skan } 398169691Skan 399169691Skan __weak_count<_Lp>& 400169691Skan operator=(const __weak_count<_Lp>& __r) // nothrow 401169691Skan { 402169691Skan _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 403169691Skan if (__tmp != 0) 404169691Skan __tmp->_M_weak_add_ref(); 405169691Skan if (_M_pi != 0) 406169691Skan _M_pi->_M_weak_release(); 407169691Skan _M_pi = __tmp; 408169691Skan return *this; 409169691Skan } 410169691Skan 411169691Skan void 412169691Skan _M_swap(__weak_count<_Lp>& __r) // nothrow 413169691Skan { 414169691Skan _Sp_counted_base<_Lp>* __tmp = __r._M_pi; 415169691Skan __r._M_pi = _M_pi; 416169691Skan _M_pi = __tmp; 417169691Skan } 418169691Skan 419169691Skan long 420169691Skan _M_get_use_count() const // nothrow 421169691Skan { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; } 422169691Skan 423169691Skan friend inline bool 424169691Skan operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) 425169691Skan { return __a._M_pi == __b._M_pi; } 426169691Skan 427169691Skan friend inline bool 428169691Skan operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b) 429169691Skan { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); } 430169691Skan 431169691Skan private: 432169691Skan friend class __shared_count<_Lp>; 433169691Skan 434169691Skan _Sp_counted_base<_Lp>* _M_pi; 435169691Skan }; 436169691Skan 437169691Skan template<_Lock_policy _Lp> 438169691Skan inline 439169691Skan __shared_count<_Lp>:: 440169691Skan __shared_count(const __weak_count<_Lp>& __r) 441169691Skan : _M_pi(__r._M_pi) 442169691Skan { 443169691Skan if (_M_pi != 0) 444169691Skan _M_pi->_M_add_ref_lock(); 445169691Skan else 446169691Skan __throw_bad_weak_ptr(); 447169691Skan } 448169691Skan 449169691Skan 450169691Skan // Forward declarations. 451169691Skan template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 452169691Skan class __shared_ptr; 453169691Skan 454169691Skan template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 455169691Skan class __weak_ptr; 456169691Skan 457169691Skan template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> 458169691Skan class __enable_shared_from_this; 459169691Skan 460169691Skan template<typename _Tp> 461169691Skan class shared_ptr; 462169691Skan 463169691Skan template<typename _Tp> 464169691Skan class weak_ptr; 465169691Skan 466169691Skan template<typename _Tp> 467169691Skan class enable_shared_from_this; 468169691Skan 469169691Skan // Support for enable_shared_from_this. 470169691Skan 471169691Skan // Friend of __enable_shared_from_this. 472169691Skan template<_Lock_policy _Lp, typename _Tp1, typename _Tp2> 473169691Skan void 474169691Skan __enable_shared_from_this_helper(const __shared_count<_Lp>&, 475169691Skan const __enable_shared_from_this<_Tp1, 476169691Skan _Lp>*, const _Tp2*); 477169691Skan 478169691Skan // Friend of enable_shared_from_this. 479169691Skan template<typename _Tp1, typename _Tp2> 480169691Skan void 481169691Skan __enable_shared_from_this_helper(const __shared_count<>&, 482169691Skan const enable_shared_from_this<_Tp1>*, 483169691Skan const _Tp2*); 484169691Skan 485169691Skan template<_Lock_policy _Lp> 486169691Skan inline void 487169691Skan __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) 488169691Skan { } 489169691Skan 490169691Skan 491169691Skan struct __static_cast_tag { }; 492169691Skan struct __const_cast_tag { }; 493169691Skan struct __dynamic_cast_tag { }; 494169691Skan 495169691Skan /** 496169691Skan * @class shared_ptr <tr1/memory> 497169691Skan * 498169691Skan * A smart pointer with reference-counted copy semantics. 499169691Skan * The object pointed to is deleted when the last shared_ptr pointing to 500169691Skan * it is destroyed or reset. 501169691Skan */ 502169691Skan template<typename _Tp, _Lock_policy _Lp> 503169691Skan class __shared_ptr 504169691Skan { 505169691Skan public: 506169691Skan typedef _Tp element_type; 507169691Skan 508169691Skan /** @brief Construct an empty %__shared_ptr. 509169691Skan * @post use_count()==0 && get()==0 510169691Skan */ 511169691Skan __shared_ptr() 512169691Skan : _M_ptr(0), _M_refcount() // never throws 513169691Skan { } 514169691Skan 515169691Skan /** @brief Construct a %__shared_ptr that owns the pointer @a __p. 516169691Skan * @param __p A pointer that is convertible to element_type*. 517169691Skan * @post use_count() == 1 && get() == __p 518169691Skan * @throw std::bad_alloc, in which case @c delete @a __p is called. 519169691Skan */ 520169691Skan template<typename _Tp1> 521169691Skan explicit 522169691Skan __shared_ptr(_Tp1* __p) 523169691Skan : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>()) 524169691Skan { 525169691Skan __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 526169691Skan // __glibcxx_function_requires(_CompleteConcept<_Tp1*>) 527169691Skan __enable_shared_from_this_helper(_M_refcount, __p, __p); 528169691Skan } 529169691Skan 530169691Skan // 531169691Skan // Requirements: _Deleter' copy constructor and destructor must not throw 532169691Skan // 533169691Skan // __shared_ptr will release __p by calling __d(__p) 534169691Skan // 535169691Skan /** @brief Construct a %__shared_ptr that owns the pointer @a __p 536169691Skan * and the deleter @a __d. 537169691Skan * @param __p A pointer. 538169691Skan * @param __d A deleter. 539169691Skan * @post use_count() == 1 && get() == __p 540169691Skan * @throw std::bad_alloc, in which case @a __d(__p) is called. 541169691Skan */ 542169691Skan template<typename _Tp1, typename _Deleter> 543169691Skan __shared_ptr(_Tp1* __p, _Deleter __d) 544169691Skan : _M_ptr(__p), _M_refcount(__p, __d) 545169691Skan { 546169691Skan __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 547169691Skan // TODO requires _Deleter CopyConstructible and __d(__p) well-formed 548169691Skan __enable_shared_from_this_helper(_M_refcount, __p, __p); 549169691Skan } 550169691Skan 551169691Skan // generated copy constructor, assignment, destructor are fine. 552169691Skan 553169691Skan /** @brief If @a __r is empty, constructs an empty %__shared_ptr; 554169691Skan * otherwise construct a %__shared_ptr that shares ownership 555169691Skan * with @a __r. 556169691Skan * @param __r A %__shared_ptr. 557169691Skan * @post get() == __r.get() && use_count() == __r.use_count() 558169691Skan * @throw std::bad_alloc, in which case 559169691Skan */ 560169691Skan template<typename _Tp1> 561169691Skan __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 562169691Skan : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 563169691Skan { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 564169691Skan 565169691Skan /** @brief Constructs a %__shared_ptr that shares ownership with @a __r 566169691Skan * and stores a copy of the pointer stored in @a __r. 567169691Skan * @param __r A weak_ptr. 568169691Skan * @post use_count() == __r.use_count() 569169691Skan * @throw bad_weak_ptr when __r.expired(), 570169691Skan * in which case the constructor has no effect. 571169691Skan */ 572169691Skan template<typename _Tp1> 573169691Skan explicit 574169691Skan __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 575169691Skan : _M_refcount(__r._M_refcount) // may throw 576169691Skan { 577169691Skan __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 578169691Skan // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount) 579169691Skan // did not throw. 580169691Skan _M_ptr = __r._M_ptr; 581169691Skan } 582169691Skan 583169691Skan /** 584169691Skan * @post use_count() == 1 and __r.get() == 0 585169691Skan */ 586169691Skan template<typename _Tp1> 587169691Skan explicit 588169691Skan __shared_ptr(std::auto_ptr<_Tp1>& __r) 589169691Skan : _M_ptr(__r.get()), _M_refcount() 590169691Skan { 591169691Skan // TODO requires __r.release() convertible to _Tp*, _Tp1 is complete, 592169691Skan // delete __r.release() well-formed 593169691Skan _Tp1* __tmp = __r.get(); 594169691Skan _M_refcount = __shared_count<_Lp>(__r); 595169691Skan __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp); 596169691Skan } 597169691Skan 598169691Skan template<typename _Tp1> 599169691Skan __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag) 600169691Skan : _M_ptr(static_cast<element_type*>(__r._M_ptr)), 601169691Skan _M_refcount(__r._M_refcount) 602169691Skan { } 603169691Skan 604169691Skan template<typename _Tp1> 605169691Skan __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag) 606169691Skan : _M_ptr(const_cast<element_type*>(__r._M_ptr)), 607169691Skan _M_refcount(__r._M_refcount) 608169691Skan { } 609169691Skan 610169691Skan template<typename _Tp1> 611169691Skan __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag) 612169691Skan : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)), 613169691Skan _M_refcount(__r._M_refcount) 614169691Skan { 615169691Skan if (_M_ptr == 0) // need to allocate new counter -- the cast failed 616169691Skan _M_refcount = __shared_count<_Lp>(); 617169691Skan } 618169691Skan 619169691Skan template<typename _Tp1> 620169691Skan __shared_ptr& 621169691Skan operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 622169691Skan { 623169691Skan _M_ptr = __r._M_ptr; 624169691Skan _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw 625169691Skan return *this; 626169691Skan } 627169691Skan 628169691Skan template<typename _Tp1> 629169691Skan __shared_ptr& 630169691Skan operator=(std::auto_ptr<_Tp1>& __r) 631169691Skan { 632169691Skan __shared_ptr(__r).swap(*this); 633169691Skan return *this; 634169691Skan } 635169691Skan 636169691Skan void 637169691Skan reset() // never throws 638169691Skan { __shared_ptr().swap(*this); } 639169691Skan 640169691Skan template<typename _Tp1> 641169691Skan void 642169691Skan reset(_Tp1* __p) // _Tp1 must be complete. 643169691Skan { 644169691Skan // Catch self-reset errors. 645169691Skan _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 646169691Skan __shared_ptr(__p).swap(*this); 647169691Skan } 648169691Skan 649169691Skan template<typename _Tp1, typename _Deleter> 650169691Skan void 651169691Skan reset(_Tp1* __p, _Deleter __d) 652169691Skan { __shared_ptr(__p, __d).swap(*this); } 653169691Skan 654169691Skan // Allow class instantiation when _Tp is [cv-qual] void. 655169691Skan typename add_reference<_Tp>::type 656169691Skan operator*() const // never throws 657169691Skan { 658169691Skan _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 659169691Skan return *_M_ptr; 660169691Skan } 661169691Skan 662169691Skan _Tp* 663169691Skan operator->() const // never throws 664169691Skan { 665169691Skan _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0); 666169691Skan return _M_ptr; 667169691Skan } 668169691Skan 669169691Skan _Tp* 670169691Skan get() const // never throws 671169691Skan { return _M_ptr; } 672169691Skan 673169691Skan // Implicit conversion to "bool" 674169691Skan private: 675169691Skan typedef _Tp* __shared_ptr::*__unspecified_bool_type; 676169691Skan 677169691Skan public: 678169691Skan operator __unspecified_bool_type() const // never throws 679169691Skan { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; } 680169691Skan 681169691Skan bool 682169691Skan unique() const // never throws 683169691Skan { return _M_refcount._M_unique(); } 684169691Skan 685169691Skan long 686169691Skan use_count() const // never throws 687169691Skan { return _M_refcount._M_get_use_count(); } 688169691Skan 689169691Skan void 690169691Skan swap(__shared_ptr<_Tp, _Lp>& __other) // never throws 691169691Skan { 692169691Skan std::swap(_M_ptr, __other._M_ptr); 693169691Skan _M_refcount._M_swap(__other._M_refcount); 694169691Skan } 695169691Skan 696169691Skan private: 697169691Skan void* 698169691Skan _M_get_deleter(const std::type_info& __ti) const 699169691Skan { return _M_refcount._M_get_deleter(__ti); } 700169691Skan 701169691Skan template<typename _Tp1, _Lock_policy _Lp1> 702169691Skan bool 703169691Skan _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const 704169691Skan { return _M_refcount < __rhs._M_refcount; } 705169691Skan 706169691Skan template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 707169691Skan template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 708169691Skan 709169691Skan template<typename _Del, typename _Tp1, _Lock_policy _Lp1> 710169691Skan friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&); 711169691Skan 712169691Skan // Friends injected into enclosing namespace and found by ADL: 713169691Skan template<typename _Tp1> 714169691Skan friend inline bool 715169691Skan operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 716169691Skan { return __a.get() == __b.get(); } 717169691Skan 718169691Skan template<typename _Tp1> 719169691Skan friend inline bool 720169691Skan operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 721169691Skan { return __a.get() != __b.get(); } 722169691Skan 723169691Skan template<typename _Tp1> 724169691Skan friend inline bool 725169691Skan operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b) 726169691Skan { return __a._M_less(__b); } 727169691Skan 728169691Skan _Tp* _M_ptr; // Contained pointer. 729169691Skan __shared_count<_Lp> _M_refcount; // Reference counter. 730169691Skan }; 731169691Skan 732169691Skan // 2.2.3.8 shared_ptr specialized algorithms. 733169691Skan template<typename _Tp, _Lock_policy _Lp> 734169691Skan inline void 735169691Skan swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) 736169691Skan { __a.swap(__b); } 737169691Skan 738169691Skan // 2.2.3.9 shared_ptr casts 739169691Skan /** @warning The seemingly equivalent 740169691Skan * <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code> 741169691Skan * will eventually result in undefined behaviour, 742169691Skan * attempting to delete the same object twice. 743169691Skan */ 744169691Skan template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 745169691Skan __shared_ptr<_Tp, _Lp> 746169691Skan static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 747169691Skan { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); } 748169691Skan 749169691Skan /** @warning The seemingly equivalent 750169691Skan * <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code> 751169691Skan * will eventually result in undefined behaviour, 752169691Skan * attempting to delete the same object twice. 753169691Skan */ 754169691Skan template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 755169691Skan __shared_ptr<_Tp, _Lp> 756169691Skan const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 757169691Skan { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); } 758169691Skan 759169691Skan /** @warning The seemingly equivalent 760169691Skan * <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code> 761169691Skan * will eventually result in undefined behaviour, 762169691Skan * attempting to delete the same object twice. 763169691Skan */ 764169691Skan template<typename _Tp, typename _Tp1, _Lock_policy _Lp> 765169691Skan __shared_ptr<_Tp, _Lp> 766169691Skan dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) 767169691Skan { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); } 768169691Skan 769169691Skan // 2.2.3.7 shared_ptr I/O 770169691Skan template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> 771169691Skan std::basic_ostream<_Ch, _Tr>& 772169691Skan operator<<(std::basic_ostream<_Ch, _Tr>& __os, 773169691Skan const __shared_ptr<_Tp, _Lp>& __p) 774169691Skan { 775169691Skan __os << __p.get(); 776169691Skan return __os; 777169691Skan } 778169691Skan 779169691Skan // 2.2.3.10 shared_ptr get_deleter (experimental) 780169691Skan template<typename _Del, typename _Tp, _Lock_policy _Lp> 781169691Skan inline _Del* 782169691Skan get_deleter(const __shared_ptr<_Tp, _Lp>& __p) 783169691Skan { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); } 784169691Skan 785169691Skan 786169691Skan template<typename _Tp, _Lock_policy _Lp> 787169691Skan class __weak_ptr 788169691Skan { 789169691Skan public: 790169691Skan typedef _Tp element_type; 791169691Skan 792169691Skan __weak_ptr() 793169691Skan : _M_ptr(0), _M_refcount() // never throws 794169691Skan { } 795169691Skan 796169691Skan // Generated copy constructor, assignment, destructor are fine. 797169691Skan 798169691Skan // The "obvious" converting constructor implementation: 799169691Skan // 800169691Skan // template<typename _Tp1> 801169691Skan // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 802169691Skan // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 803169691Skan // { } 804169691Skan // 805169691Skan // has a serious problem. 806169691Skan // 807169691Skan // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr) 808169691Skan // conversion may require access to *__r._M_ptr (virtual inheritance). 809169691Skan // 810169691Skan // It is not possible to avoid spurious access violations since 811169691Skan // in multithreaded programs __r._M_ptr may be invalidated at any point. 812169691Skan template<typename _Tp1> 813169691Skan __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) 814169691Skan : _M_refcount(__r._M_refcount) // never throws 815169691Skan { 816169691Skan __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) 817169691Skan _M_ptr = __r.lock().get(); 818169691Skan } 819169691Skan 820169691Skan template<typename _Tp1> 821169691Skan __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) 822169691Skan : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws 823169691Skan { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) } 824169691Skan 825169691Skan template<typename _Tp1> 826169691Skan __weak_ptr& 827169691Skan operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws 828169691Skan { 829169691Skan _M_ptr = __r.lock().get(); 830169691Skan _M_refcount = __r._M_refcount; 831169691Skan return *this; 832169691Skan } 833169691Skan 834169691Skan template<typename _Tp1> 835169691Skan __weak_ptr& 836169691Skan operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws 837169691Skan { 838169691Skan _M_ptr = __r._M_ptr; 839169691Skan _M_refcount = __r._M_refcount; 840169691Skan return *this; 841169691Skan } 842169691Skan 843169691Skan __shared_ptr<_Tp, _Lp> 844169691Skan lock() const // never throws 845169691Skan { 846169691Skan#ifdef __GTHREADS 847169691Skan // Optimization: avoid throw overhead. 848169691Skan if (expired()) 849169691Skan return __shared_ptr<element_type, _Lp>(); 850169691Skan 851169691Skan try 852169691Skan { 853169691Skan return __shared_ptr<element_type, _Lp>(*this); 854169691Skan } 855169691Skan catch(const bad_weak_ptr&) 856169691Skan { 857169691Skan // Q: How can we get here? 858169691Skan // A: Another thread may have invalidated r after the 859169691Skan // use_count test above. 860229551Spfg return __shared_ptr<element_type, _Lp>(); 861169691Skan } 862169691Skan 863169691Skan#else 864169691Skan // Optimization: avoid try/catch overhead when single threaded. 865169691Skan return expired() ? __shared_ptr<element_type, _Lp>() 866169691Skan : __shared_ptr<element_type, _Lp>(*this); 867169691Skan 868169691Skan#endif 869169691Skan } // XXX MT 870169691Skan 871169691Skan long 872169691Skan use_count() const // never throws 873169691Skan { return _M_refcount._M_get_use_count(); } 874169691Skan 875169691Skan bool 876169691Skan expired() const // never throws 877169691Skan { return _M_refcount._M_get_use_count() == 0; } 878169691Skan 879169691Skan void 880169691Skan reset() // never throws 881169691Skan { __weak_ptr().swap(*this); } 882169691Skan 883169691Skan void 884169691Skan swap(__weak_ptr& __s) // never throws 885169691Skan { 886169691Skan std::swap(_M_ptr, __s._M_ptr); 887169691Skan _M_refcount._M_swap(__s._M_refcount); 888169691Skan } 889169691Skan 890169691Skan private: 891169691Skan // Used by __enable_shared_from_this. 892169691Skan void 893169691Skan _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) 894169691Skan { 895169691Skan _M_ptr = __ptr; 896169691Skan _M_refcount = __refcount; 897169691Skan } 898169691Skan 899169691Skan template<typename _Tp1> 900169691Skan bool 901169691Skan _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const 902169691Skan { return _M_refcount < __rhs._M_refcount; } 903169691Skan 904169691Skan template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr; 905169691Skan template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr; 906169691Skan friend class __enable_shared_from_this<_Tp, _Lp>; 907169691Skan friend class enable_shared_from_this<_Tp>; 908169691Skan 909169691Skan // Friend injected into namespace and found by ADL. 910169691Skan template<typename _Tp1> 911169691Skan friend inline bool 912169691Skan operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs) 913169691Skan { return __lhs._M_less(__rhs); } 914169691Skan 915169691Skan _Tp* _M_ptr; // Contained pointer. 916169691Skan __weak_count<_Lp> _M_refcount; // Reference counter. 917169691Skan }; 918169691Skan 919169691Skan // 2.2.4.7 weak_ptr specialized algorithms. 920169691Skan template<typename _Tp, _Lock_policy _Lp> 921169691Skan inline void 922169691Skan swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) 923169691Skan { __a.swap(__b); } 924169691Skan 925169691Skan 926169691Skan template<typename _Tp, _Lock_policy _Lp> 927169691Skan class __enable_shared_from_this 928169691Skan { 929169691Skan protected: 930169691Skan __enable_shared_from_this() { } 931169691Skan 932169691Skan __enable_shared_from_this(const __enable_shared_from_this&) { } 933169691Skan 934169691Skan __enable_shared_from_this& 935169691Skan operator=(const __enable_shared_from_this&) 936169691Skan { return *this; } 937169691Skan 938169691Skan ~__enable_shared_from_this() { } 939169691Skan 940169691Skan public: 941169691Skan __shared_ptr<_Tp, _Lp> 942169691Skan shared_from_this() 943169691Skan { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); } 944169691Skan 945169691Skan __shared_ptr<const _Tp, _Lp> 946169691Skan shared_from_this() const 947169691Skan { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); } 948169691Skan 949169691Skan private: 950169691Skan template<typename _Tp1> 951169691Skan void 952169691Skan _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const 953169691Skan { _M_weak_this._M_assign(__p, __n); } 954169691Skan 955169691Skan template<typename _Tp1> 956169691Skan friend void 957169691Skan __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn, 958169691Skan const __enable_shared_from_this* __pe, 959169691Skan const _Tp1* __px) 960169691Skan { 961169691Skan if (__pe != 0) 962169691Skan __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 963169691Skan } 964169691Skan 965169691Skan mutable __weak_ptr<_Tp, _Lp> _M_weak_this; 966169691Skan }; 967169691Skan 968169691Skan 969169691Skan // The actual TR1 shared_ptr, with forwarding constructors and 970169691Skan // assignment operators. 971169691Skan template<typename _Tp> 972169691Skan class shared_ptr 973169691Skan : public __shared_ptr<_Tp> 974169691Skan { 975169691Skan public: 976169691Skan shared_ptr() 977169691Skan : __shared_ptr<_Tp>() { } 978169691Skan 979169691Skan template<typename _Tp1> 980169691Skan explicit 981169691Skan shared_ptr(_Tp1* __p) 982169691Skan : __shared_ptr<_Tp>(__p) { } 983169691Skan 984169691Skan template<typename _Tp1, typename _Deleter> 985169691Skan shared_ptr(_Tp1* __p, _Deleter __d) 986169691Skan : __shared_ptr<_Tp>(__p, __d) { } 987169691Skan 988169691Skan template<typename _Tp1> 989169691Skan shared_ptr(const shared_ptr<_Tp1>& __r) 990169691Skan : __shared_ptr<_Tp>(__r) { } 991169691Skan 992169691Skan template<typename _Tp1> 993169691Skan explicit 994169691Skan shared_ptr(const weak_ptr<_Tp1>& __r) 995169691Skan : __shared_ptr<_Tp>(__r) { } 996169691Skan 997169691Skan template<typename _Tp1> 998169691Skan explicit 999169691Skan shared_ptr(std::auto_ptr<_Tp1>& __r) 1000169691Skan : __shared_ptr<_Tp>(__r) { } 1001169691Skan 1002169691Skan template<typename _Tp1> 1003169691Skan shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag) 1004169691Skan : __shared_ptr<_Tp>(__r, __static_cast_tag()) { } 1005169691Skan 1006169691Skan template<typename _Tp1> 1007169691Skan shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag) 1008169691Skan : __shared_ptr<_Tp>(__r, __const_cast_tag()) { } 1009169691Skan 1010169691Skan template<typename _Tp1> 1011169691Skan shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag) 1012169691Skan : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { } 1013169691Skan 1014169691Skan template<typename _Tp1> 1015169691Skan shared_ptr& 1016169691Skan operator=(const shared_ptr<_Tp1>& __r) // never throws 1017169691Skan { 1018169691Skan this->__shared_ptr<_Tp>::operator=(__r); 1019169691Skan return *this; 1020169691Skan } 1021169691Skan 1022169691Skan template<typename _Tp1> 1023169691Skan shared_ptr& 1024169691Skan operator=(std::auto_ptr<_Tp1>& __r) 1025169691Skan { 1026169691Skan this->__shared_ptr<_Tp>::operator=(__r); 1027169691Skan return *this; 1028169691Skan } 1029169691Skan }; 1030169691Skan 1031169691Skan template<typename _Tp, typename _Tp1> 1032169691Skan shared_ptr<_Tp> 1033169691Skan static_pointer_cast(const shared_ptr<_Tp1>& __r) 1034169691Skan { return shared_ptr<_Tp>(__r, __static_cast_tag()); } 1035169691Skan 1036169691Skan template<typename _Tp, typename _Tp1> 1037169691Skan shared_ptr<_Tp> 1038169691Skan const_pointer_cast(const shared_ptr<_Tp1>& __r) 1039169691Skan { return shared_ptr<_Tp>(__r, __const_cast_tag()); } 1040169691Skan 1041169691Skan template<typename _Tp, typename _Tp1> 1042169691Skan shared_ptr<_Tp> 1043169691Skan dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) 1044169691Skan { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); } 1045169691Skan 1046169691Skan 1047169691Skan // The actual TR1 weak_ptr, with forwarding constructors and 1048169691Skan // assignment operators. 1049169691Skan template<typename _Tp> 1050169691Skan class weak_ptr 1051169691Skan : public __weak_ptr<_Tp> 1052169691Skan { 1053169691Skan public: 1054169691Skan weak_ptr() 1055169691Skan : __weak_ptr<_Tp>() { } 1056169691Skan 1057169691Skan template<typename _Tp1> 1058169691Skan weak_ptr(const weak_ptr<_Tp1>& __r) 1059169691Skan : __weak_ptr<_Tp>(__r) { } 1060169691Skan 1061169691Skan template<typename _Tp1> 1062169691Skan weak_ptr(const shared_ptr<_Tp1>& __r) 1063169691Skan : __weak_ptr<_Tp>(__r) { } 1064169691Skan 1065169691Skan template<typename _Tp1> 1066169691Skan weak_ptr& 1067169691Skan operator=(const weak_ptr<_Tp1>& __r) // never throws 1068169691Skan { 1069169691Skan this->__weak_ptr<_Tp>::operator=(__r); 1070169691Skan return *this; 1071169691Skan } 1072169691Skan 1073169691Skan template<typename _Tp1> 1074169691Skan weak_ptr& 1075169691Skan operator=(const shared_ptr<_Tp1>& __r) // never throws 1076169691Skan { 1077169691Skan this->__weak_ptr<_Tp>::operator=(__r); 1078169691Skan return *this; 1079169691Skan } 1080169691Skan 1081169691Skan shared_ptr<_Tp> 1082169691Skan lock() const // never throws 1083169691Skan { 1084169691Skan#ifdef __GTHREADS 1085169691Skan if (this->expired()) 1086169691Skan return shared_ptr<_Tp>(); 1087169691Skan 1088169691Skan try 1089169691Skan { 1090169691Skan return shared_ptr<_Tp>(*this); 1091169691Skan } 1092169691Skan catch(const bad_weak_ptr&) 1093169691Skan { 1094169691Skan return shared_ptr<_Tp>(); 1095169691Skan } 1096169691Skan#else 1097169691Skan return this->expired() ? shared_ptr<_Tp>() 1098169691Skan : shared_ptr<_Tp>(*this); 1099169691Skan#endif 1100169691Skan } 1101169691Skan }; 1102169691Skan 1103169691Skan 1104169691Skan template<typename _Tp> 1105169691Skan class enable_shared_from_this 1106169691Skan { 1107169691Skan protected: 1108169691Skan enable_shared_from_this() { } 1109169691Skan 1110169691Skan enable_shared_from_this(const enable_shared_from_this&) { } 1111169691Skan 1112169691Skan enable_shared_from_this& 1113169691Skan operator=(const enable_shared_from_this&) 1114169691Skan { return *this; } 1115169691Skan 1116169691Skan ~enable_shared_from_this() { } 1117169691Skan 1118169691Skan public: 1119169691Skan shared_ptr<_Tp> 1120169691Skan shared_from_this() 1121169691Skan { return shared_ptr<_Tp>(this->_M_weak_this); } 1122169691Skan 1123169691Skan shared_ptr<const _Tp> 1124169691Skan shared_from_this() const 1125169691Skan { return shared_ptr<const _Tp>(this->_M_weak_this); } 1126169691Skan 1127169691Skan private: 1128169691Skan template<typename _Tp1> 1129169691Skan void 1130169691Skan _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const 1131169691Skan { _M_weak_this._M_assign(__p, __n); } 1132169691Skan 1133169691Skan template<typename _Tp1> 1134169691Skan friend void 1135169691Skan __enable_shared_from_this_helper(const __shared_count<>& __pn, 1136169691Skan const enable_shared_from_this* __pe, 1137169691Skan const _Tp1* __px) 1138169691Skan { 1139169691Skan if (__pe != 0) 1140169691Skan __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); 1141169691Skan } 1142169691Skan 1143169691Skan mutable weak_ptr<_Tp> _M_weak_this; 1144169691Skan }; 1145169691Skan 1146169691Skan_GLIBCXX_END_NAMESPACE 1147169691Skan} // namespace std 1148169691Skan 1149169691Skan#endif 1150