# shared_ptr_base.h

Go to the documentation of this file.

    00001 // shared_ptr and weak_ptr implementation details -*- C++ -*-
    00002
    00003 // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the
    00007 // terms of the GNU General Public License as published by the
    00008 // Free Software Foundation; either version 3, or (at your option)
    00009 // any later version.
    00010
    00011 // This library is distributed in the hope that it will be useful,
    00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014 // GNU General Public License for more details.
    00015
    00016 // Under Section 7 of GPL version 3, you are granted additional
    00017 // permissions described in the GCC Runtime Library Exception, version
    00018 // 3.1, as published by the Free Software Foundation.
    00019
    00020 // You should have received a copy of the GNU General Public License and
    00021 // a copy of the GCC Runtime Library Exception along with this program;
    00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    00023 // <http://www.gnu.org/licenses/>.
    00024
    00025 // GCC Note: Based on files from version 1.32.0 of the Boost library.
    00026
    00027 //  shared_count.hpp
    00028 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
    00029
    00030 //  shared_ptr.hpp
    00031 //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
    00032 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
    00033
    00034 //  weak_ptr.hpp
    00035 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
    00036
    00037 //  enable_shared_from_this.hpp
    00038 //  Copyright (C) 2002 Peter Dimov
    00039
    00040 // Distributed under the Boost Software License, Version 1.0. (See
    00041 // accompanying file LICENSE_1_0.txt or copy at
    00042 // http://www.boost.org/LICENSE_1_0.txt)
    00043
    00044 /** @file bits/shared_ptr_base.h
    00045  *  This is an internal header file, included by other library headers.
    00046  *  You should not attempt to use it directly.
    00047  */
    00048
    00049 #ifndef _SHARED_PTR_BASE_H
    00050 #define _SHARED_PTR_BASE_H 1
    00051
    00052 _GLIBCXX_BEGIN_NAMESPACE(std)
    00053
    00054   // Forward declarations.
    00055   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    00056     class __shared_ptr;
    00057
    00058   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    00059     class __weak_ptr;
    00060
    00061   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    00062     class __enable_shared_from_this;
    00063
    00064   template<typename _Tp>
    00065     class shared_ptr;
    00066
    00067   template<typename _Tp>
    00068     class weak_ptr;
    00069
    00070   template<typename _Tp>
    00071     struct owner_less;
    00072
    00073   template<typename _Tp>
    00074     class enable_shared_from_this;
    00075
    00076   template<_Lock_policy _Lp = __default_lock_policy>
    00077     class __weak_count;
    00078
    00079   template<_Lock_policy _Lp = __default_lock_policy>
    00080     class __shared_count;
    00081
    00082
    00083   // Counted ptr with no deleter or allocator support
    00084   template<typename _Ptr, _Lock_policy _Lp>
    00085     class _Sp_counted_ptr : public _Sp_counted_base<_Lp>
    00086     {
    00087     public:
    00088       _Sp_counted_ptr(_Ptr __p)
    00089       : _M_ptr(__p) { }
    00090
    00091       virtual void
    00092       _M_dispose() // nothrow
    00093       { delete _M_ptr; }
    00094
    00095       virtual void
    00096       _M_destroy() // nothrow
    00097       { delete this; }
    00098
    00099       virtual void*
    00100       _M_get_deleter(const std::type_info& __ti)
    00101       { return 0; }
    00102
    00103       _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
    00104       _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
    00105
    00106     protected:
    00107       _Ptr             _M_ptr;  // copy constructor must not throw
    00108     };
    00109
    00110   // Support for custom deleter and/or allocator
    00111   template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
    00112     class _Sp_counted_deleter : public _Sp_counted_ptr<_Ptr, _Lp>
    00113     {
    00114       typedef typename _Alloc::template
    00115       rebind<_Sp_counted_deleter>::other _My_alloc_type;
    00116
    00117       // Helper class that stores the Deleter and also acts as an allocator.
    00118       // Used to dispose of the owned pointer and the internal refcount
    00119       // Requires that copies of _Alloc can free each other's memory.
    00120       struct _My_Deleter
    00121       : public _My_alloc_type    // copy constructor must not throw
    00122       {
    00123     _Deleter _M_del;         // copy constructor must not throw
    00124     _My_Deleter(_Deleter __d, const _Alloc& __a)
    00125       : _My_alloc_type(__a), _M_del(__d) { }
    00126       };
    00127
    00128     protected:
    00129       typedef _Sp_counted_ptr<_Ptr, _Lp> _Base_type;
    00130
    00131     public:
    00132       // __d(__p) must not throw.
    00133       _Sp_counted_deleter(_Ptr __p, _Deleter __d)
    00134       : _Base_type(__p), _M_del(__d, _Alloc()) { }
    00135
    00136       // __d(__p) must not throw.
    00137       _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a)
    00138       : _Base_type(__p), _M_del(__d, __a) { }
    00139
    00140       virtual void
    00141       _M_dispose() // nothrow
    00142       { _M_del._M_del(_Base_type::_M_ptr); }
    00143
    00144       virtual void
    00145       _M_destroy() // nothrow
    00146       {
    00147     _My_alloc_type __a(_M_del);
    00148     this->~_Sp_counted_deleter();
    00149     __a.deallocate(this, 1);
    00150       }
    00151
    00152       virtual void*
    00153       _M_get_deleter(const std::type_info& __ti)
    00154       {
    00155 #ifdef __GXX_RTTI
    00156         return __ti == typeid(_Deleter) ? &_M_del._M_del : 0;
    00157 #else
    00158         return 0;
    00159 #endif
    00160       }
    00161
    00162     protected:
    00163       _My_Deleter      _M_del;  // copy constructor must not throw
    00164     };
    00165
    00166   // helpers for make_shared / allocate_shared
    00167
    00168   template<typename _Tp>
    00169     struct _Sp_destroy_inplace
    00170     {
    00171       void operator()(_Tp* __p) const { if (__p) __p->~_Tp(); }
    00172     };
    00173
    00174   struct _Sp_make_shared_tag { };
    00175
    00176   template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
    00177     class _Sp_counted_ptr_inplace
    00178     : public _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp>
    00179     {
    00180       typedef _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp>
    00181     _Base_type;
    00182
    00183     public:
    00184       _Sp_counted_ptr_inplace(_Alloc __a)
    00185       : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a)
    00186       , _M_storage()
    00187       {
    00188     void* __p = &_M_storage;
    00189     ::new (__p) _Tp();  // might throw
    00190     _Base_type::_Base_type::_M_ptr = static_cast<_Tp*>(__p);
    00191       }
    00192
    00193       template<typename... _Args>
    00194     _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
    00195     : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a)
    00196     , _M_storage()
    00197     {
    00198       void* __p = &_M_storage;
    00199       ::new (__p) _Tp(std::forward<_Args>(__args)...);  // might throw
    00200       _Base_type::_Base_type::_M_ptr = static_cast<_Tp*>(__p);
    00201     }
    00202
    00203       // Override because the allocator needs to know the dynamic type
    00204       virtual void
    00205       _M_destroy() // nothrow
    00206       {
    00207     typedef typename _Alloc::template
    00208         rebind<_Sp_counted_ptr_inplace>::other _My_alloc_type;
    00209     _My_alloc_type __a(_Base_type::_M_del);
    00210     this->~_Sp_counted_ptr_inplace();
    00211     __a.deallocate(this, 1);
    00212       }
    00213
    00214       // Sneaky trick so __shared_ptr can get the managed pointer
    00215       virtual void*
    00216       _M_get_deleter(const std::type_info& __ti)
    00217       {
    00218 #ifdef __GXX_RTTI
    00219     return __ti == typeid(_Sp_make_shared_tag)
    00220            ? static_cast<void*>(&_M_storage)
    00221            : _Base_type::_M_get_deleter(__ti);
    00222 #else
    00223         return 0;
    00224 #endif
    00225       }
    00226
    00227     private:
    00228       typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type
    00229     _M_storage;
    00230     };
    00231
    00232   template<_Lock_policy _Lp>
    00233     class __shared_count
    00234     {
    00235     public:
    00236       __shared_count() : _M_pi(0) // nothrow
    00237       { }
    00238
    00239       template<typename _Ptr>
    00240     __shared_count(_Ptr __p) : _M_pi(0)
    00241     {
    00242       __try
    00243         {
    00244           _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
    00245         }
    00246       __catch(...)
    00247         {
    00248           delete __p;
    00249           __throw_exception_again;
    00250         }
    00251     }
    00252
    00253       template<typename _Ptr, typename _Deleter>
    00254     __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
    00255     {
    00256       // The allocator's value_type doesn't matter, will rebind it anyway.
    00257       typedef std::allocator<int> _Alloc;
    00258       typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
    00259       typedef std::allocator<_Sp_cd_type> _Alloc2;
    00260       _Alloc2 __a2;
    00261       __try
    00262         {
    00263           _M_pi = __a2.allocate(1);
    00264           ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d);
    00265         }
    00266       __catch(...)
    00267         {
    00268           __d(__p); // Call _Deleter on __p.
    00269           if (_M_pi)
    00270         __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1);
    00271           __throw_exception_again;
    00272         }
    00273     }
    00274
    00275       template<typename _Ptr, typename _Deleter, typename _Alloc>
    00276     __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
    00277     {
    00278       typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
    00279       typedef typename _Alloc::template rebind<_Sp_cd_type>::other _Alloc2;
    00280       _Alloc2 __a2(__a);
    00281       __try
    00282         {
    00283           _M_pi = __a2.allocate(1);
    00284           ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d, __a);
    00285         }
    00286       __catch(...)
    00287         {
    00288           __d(__p); // Call _Deleter on __p.
    00289           if (_M_pi)
    00290         __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1);
    00291           __throw_exception_again;
    00292         }
    00293     }
    00294
    00295       template<typename _Tp, typename _Alloc, typename... _Args>
    00296     __shared_count(_Sp_make_shared_tag, _Tp*, _Alloc __a, _Args&&... __args)
    00297     : _M_pi(0)
    00298     {
    00299       typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
    00300       typedef typename _Alloc::template rebind<_Sp_cp_type>::other _Alloc2;
    00301       _Alloc2 __a2(__a);
    00302       __try
    00303         {
    00304           _M_pi = __a2.allocate(1);
    00305           ::new(static_cast<void*>(_M_pi)) _Sp_cp_type(__a,
    00306             std::forward<_Args>(__args)...);
    00307         }
    00308       __catch(...)
    00309         {
    00310           if (_M_pi)
    00311         __a2.deallocate(static_cast<_Sp_cp_type*>(_M_pi), 1);
    00312           __throw_exception_again;
    00313         }
    00314     }
    00315
    00316 #if _GLIBCXX_DEPRECATED
    00317       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
    00318       template<typename _Tp>
    00319     __shared_count(std::auto_ptr<_Tp>&& __r)
    00320     : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get()))
    00321     { __r.release(); }
    00322 #endif
    00323
    00324       // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
    00325       template<typename _Tp, typename _Del>
    00326     __shared_count(std::unique_ptr<_Tp, _Del>&& __r)
    00327     : _M_pi(_S_create_from_up(std::move(__r)))
    00328     { __r.release(); }
    00329
    00330       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
    00331       explicit __shared_count(const __weak_count<_Lp>& __r);
    00332
    00333       ~__shared_count() // nothrow
    00334       {
    00335     if (_M_pi != 0)
    00336       _M_pi->_M_release();
    00337       }
    00338
    00339       __shared_count(const __shared_count& __r)
    00340       : _M_pi(__r._M_pi) // nothrow
    00341       {
    00342     if (_M_pi != 0)
    00343       _M_pi->_M_add_ref_copy();
    00344       }
    00345
    00346       __shared_count&
    00347       operator=(const __shared_count& __r) // nothrow
    00348       {
    00349     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00350     if (__tmp != _M_pi)
    00351       {
    00352         if (__tmp != 0)
    00353           __tmp->_M_add_ref_copy();
    00354         if (_M_pi != 0)
    00355           _M_pi->_M_release();
    00356         _M_pi = __tmp;
    00357       }
    00358     return *this;
    00359       }
    00360
    00361       void
    00362       _M_swap(__shared_count& __r) // nothrow
    00363       {
    00364     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00365     __r._M_pi = _M_pi;
    00366     _M_pi = __tmp;
    00367       }
    00368
    00369       long
    00370       _M_get_use_count() const // nothrow
    00371       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
    00372
    00373       bool
    00374       _M_unique() const // nothrow
    00375       { return this->_M_get_use_count() == 1; }
    00376
    00377       void*
    00378       _M_get_deleter(const std::type_info& __ti) const
    00379       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
    00380
    00381       bool
    00382       _M_less(const __shared_count& __rhs) const
    00383       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
    00384
    00385       bool
    00386       _M_less(const __weak_count<_Lp>& __rhs) const
    00387       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
    00388
    00389       // Friend function injected into enclosing namespace and found by ADL
    00390       friend inline bool
    00391       operator==(const __shared_count& __a, const __shared_count& __b)
    00392       { return __a._M_pi == __b._M_pi; }
    00393
    00394     private:
    00395       friend class __weak_count<_Lp>;
    00396
    00397       template<typename _Tp, typename _Del>
    00398     static _Sp_counted_base<_Lp>*
    00399     _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
    00400       typename std::enable_if<!std::is_reference<_Del>::value>::type* = 0)
    00401     {
    00402       return new _Sp_counted_deleter<_Tp*, _Del, std::allocator<_Tp>,
    00403         _Lp>(__r.get(), __r.get_deleter());
    00404     }
    00405
    00406       template<typename _Tp, typename _Del>
    00407     static _Sp_counted_base<_Lp>*
    00408     _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
    00409       typename std::enable_if<std::is_reference<_Del>::value>::type* = 0)
    00410     {
    00411       typedef typename std::remove_reference<_Del>::type _Del1;
    00412       typedef std::reference_wrapper<_Del1> _Del2;
    00413       return new _Sp_counted_deleter<_Tp*, _Del2, std::allocator<_Tp>,
    00414         _Lp>(__r.get(), std::ref(__r.get_deleter()));
    00415     }
    00416
    00417       _Sp_counted_base<_Lp>*  _M_pi;
    00418     };
    00419
    00420
    00421   template<_Lock_policy _Lp>
    00422     class __weak_count
    00423     {
    00424     public:
    00425       __weak_count() : _M_pi(0) // nothrow
    00426       { }
    00427
    00428       __weak_count(const __shared_count<_Lp>& __r) : _M_pi(__r._M_pi) // nothrow
    00429       {
    00430     if (_M_pi != 0)
    00431       _M_pi->_M_weak_add_ref();
    00432       }
    00433
    00434       __weak_count(const __weak_count<_Lp>& __r) : _M_pi(__r._M_pi) // nothrow
    00435       {
    00436     if (_M_pi != 0)
    00437       _M_pi->_M_weak_add_ref();
    00438       }
    00439
    00440       ~__weak_count() // nothrow
    00441       {
    00442     if (_M_pi != 0)
    00443       _M_pi->_M_weak_release();
    00444       }
    00445
    00446       __weak_count<_Lp>&
    00447       operator=(const __shared_count<_Lp>& __r) // nothrow
    00448       {
    00449     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00450     if (__tmp != 0)
    00451       __tmp->_M_weak_add_ref();
    00452     if (_M_pi != 0)
    00453       _M_pi->_M_weak_release();
    00454     _M_pi = __tmp;
    00455     return *this;
    00456       }
    00457
    00458       __weak_count<_Lp>&
    00459       operator=(const __weak_count<_Lp>& __r) // nothrow
    00460       {
    00461     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00462     if (__tmp != 0)
    00463       __tmp->_M_weak_add_ref();
    00464     if (_M_pi != 0)
    00465       _M_pi->_M_weak_release();
    00466     _M_pi = __tmp;
    00467     return *this;
    00468       }
    00469
    00470       void
    00471       _M_swap(__weak_count<_Lp>& __r) // nothrow
    00472       {
    00473     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00474     __r._M_pi = _M_pi;
    00475     _M_pi = __tmp;
    00476       }
    00477
    00478       long
    00479       _M_get_use_count() const // nothrow
    00480       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
    00481
    00482       bool
    00483       _M_less(const __weak_count& __rhs) const
    00484       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
    00485
    00486       bool
    00487       _M_less(const __shared_count<_Lp>& __rhs) const
    00488       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
    00489
    00490       // Friend function injected into enclosing namespace and found by ADL
    00491       friend inline bool
    00492       operator==(const __weak_count& __a, const __weak_count& __b)
    00493       { return __a._M_pi == __b._M_pi; }
    00494
    00495     private:
    00496       friend class __shared_count<_Lp>;
    00497
    00498       _Sp_counted_base<_Lp>*  _M_pi;
    00499     };
    00500
    00501   // Now that __weak_count is defined we can define this constructor:
    00502   template<_Lock_policy _Lp>
    00503     inline __shared_count<_Lp>:: __shared_count(const __weak_count<_Lp>& __r)
    00504     : _M_pi(__r._M_pi)
    00505     {
    00506       if (_M_pi != 0)
    00507     _M_pi->_M_add_ref_lock();
    00508       else
    00509     __throw_bad_weak_ptr();
    00510     }
    00511
    00512
    00513   // Support for enable_shared_from_this.
    00514
    00515   // Friend of __enable_shared_from_this.
    00516   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
    00517     void
    00518     __enable_shared_from_this_helper(const __shared_count<_Lp>&,
    00519                      const __enable_shared_from_this<_Tp1,
    00520                      _Lp>*, const _Tp2*);
    00521
    00522   // Friend of enable_shared_from_this.
    00523   template<typename _Tp1, typename _Tp2>
    00524     void
    00525     __enable_shared_from_this_helper(const __shared_count<>&,
    00526                      const enable_shared_from_this<_Tp1>*,
    00527                      const _Tp2*);
    00528
    00529   template<_Lock_policy _Lp>
    00530     inline void
    00531     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
    00532     { }
    00533
    00534
    00535   template<typename _Tp, _Lock_policy _Lp>
    00536     class __shared_ptr
    00537     {
    00538     public:
    00539       typedef _Tp   element_type;
    00540
    00541       __shared_ptr() : _M_ptr(0), _M_refcount() // never throws
    00542       { }
    00543
    00544       template<typename _Tp1>
    00545     explicit __shared_ptr(_Tp1* __p) : _M_ptr(__p), _M_refcount(__p)
    00546     {
    00547       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00548       // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
    00549       __enable_shared_from_this_helper(_M_refcount, __p, __p);
    00550     }
    00551
    00552       template<typename _Tp1, typename _Deleter>
    00553     __shared_ptr(_Tp1* __p, _Deleter __d)
    00554     : _M_ptr(__p), _M_refcount(__p, __d)
    00555     {
    00556       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00557       // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
    00558       __enable_shared_from_this_helper(_M_refcount, __p, __p);
    00559     }
    00560
    00561       template<typename _Tp1, typename _Deleter, typename _Alloc>
    00562     __shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a)
    00563     : _M_ptr(__p), _M_refcount(__p, __d, __a)
    00564     {
    00565       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00566       // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
    00567       __enable_shared_from_this_helper(_M_refcount, __p, __p);
    00568     }
    00569
    00570       template<typename _Tp1>
    00571     __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p)
    00572     : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
    00573     { }
    00574
    00575       //  generated copy constructor, assignment, destructor are fine.
    00576
    00577       template<typename _Tp1>
    00578     __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
    00579     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    00580     { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
    00581
    00582       __shared_ptr(__shared_ptr&& __r)
    00583       : _M_ptr(__r._M_ptr), _M_refcount() // never throws
    00584       {
    00585     _M_refcount._M_swap(__r._M_refcount);
    00586     __r._M_ptr = 0;
    00587       }
    00588
    00589       template<typename _Tp1>
    00590     __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r)
    00591     : _M_ptr(__r._M_ptr), _M_refcount() // never throws
    00592     {
    00593       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00594       _M_refcount._M_swap(__r._M_refcount);
    00595       __r._M_ptr = 0;
    00596     }
    00597
    00598       template<typename _Tp1>
    00599     explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    00600     : _M_refcount(__r._M_refcount) // may throw
    00601     {
    00602       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00603
    00604       // It is now safe to copy __r._M_ptr, as
    00605       // _M_refcount(__r._M_refcount) did not throw.
    00606       _M_ptr = __r._M_ptr;
    00607     }
    00608
    00609       // If an exception is thrown this constructor has no effect.
    00610       template<typename _Tp1, typename _Del>
    00611     __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
    00612     : _M_ptr(__r.get()), _M_refcount()
    00613     {
    00614       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00615       _Tp1* __tmp = __r.get();
    00616       _M_refcount = __shared_count<_Lp>(std::move(__r));
    00617       __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
    00618     }
    00619
    00620 #if _GLIBCXX_DEPRECATED
    00621       // Postcondition: use_count() == 1 and __r.get() == 0
    00622       template<typename _Tp1>
    00623     __shared_ptr(std::auto_ptr<_Tp1>&& __r)
    00624     : _M_ptr(__r.get()), _M_refcount()
    00625     {
    00626       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00627       // TODO requires _Tp1 is complete, delete __r.release() well-formed
    00628       _Tp1* __tmp = __r.get();
    00629       _M_refcount = __shared_count<_Lp>(std::move(__r));
    00630       __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
    00631     }
    00632 #endif
    00633
    00634       template<typename _Tp1>
    00635     __shared_ptr&
    00636     operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
    00637     {
    00638       _M_ptr = __r._M_ptr;
    00639       _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
    00640       return *this;
    00641     }
    00642
    00643 #if _GLIBCXX_DEPRECATED
    00644       template<typename _Tp1>
    00645     __shared_ptr&
    00646     operator=(std::auto_ptr<_Tp1>&& __r)
    00647     {
    00648       __shared_ptr(std::move(__r)).swap(*this);
    00649       return *this;
    00650     }
    00651 #endif
    00652
    00653       __shared_ptr&
    00654       operator=(__shared_ptr&& __r)
    00655       {
    00656     __shared_ptr(std::move(__r)).swap(*this);
    00657     return *this;
    00658       }
    00659
    00660       template<class _Tp1>
    00661     __shared_ptr&
    00662     operator=(__shared_ptr<_Tp1, _Lp>&& __r)
    00663     {
    00664       __shared_ptr(std::move(__r)).swap(*this);
    00665       return *this;
    00666     }
    00667
    00668       template<typename _Tp1, typename _Del>
    00669     __shared_ptr&
    00670     operator=(std::unique_ptr<_Tp1, _Del>&& __r)
    00671     {
    00672       __shared_ptr(std::move(__r)).swap(*this);
    00673       return *this;
    00674     }
    00675
    00676       void
    00677       reset() // never throws
    00678       { __shared_ptr().swap(*this); }
    00679
    00680       template<typename _Tp1>
    00681     void
    00682     reset(_Tp1* __p) // _Tp1 must be complete.
    00683     {
    00684       // Catch self-reset errors.
    00685       _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
    00686       __shared_ptr(__p).swap(*this);
    00687     }
    00688
    00689       template<typename _Tp1, typename _Deleter>
    00690     void
    00691     reset(_Tp1* __p, _Deleter __d)
    00692     { __shared_ptr(__p, __d).swap(*this); }
    00693
    00694       template<typename _Tp1, typename _Deleter, typename _Alloc>
    00695     void
    00696     reset(_Tp1* __p, _Deleter __d, const _Alloc& __a)
    00697     { __shared_ptr(__p, __d, __a).swap(*this); }
    00698
    00699       // Allow class instantiation when _Tp is [cv-qual] void.
    00700       typename std::add_lvalue_reference<_Tp>::type
    00701       operator*() const // never throws
    00702       {
    00703     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    00704     return *_M_ptr;
    00705       }
    00706
    00707       _Tp*
    00708       operator->() const // never throws
    00709       {
    00710     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    00711     return _M_ptr;
    00712       }
    00713
    00714       _Tp*
    00715       get() const // never throws
    00716       { return _M_ptr; }
    00717
    00718       explicit operator bool() const // never throws
    00719       { return _M_ptr == 0 ? false : true; }
    00720
    00721       bool
    00722       unique() const // never throws
    00723       { return _M_refcount._M_unique(); }
    00724
    00725       long
    00726       use_count() const // never throws
    00727       { return _M_refcount._M_get_use_count(); }
    00728
    00729       void
    00730       swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
    00731       {
    00732     std::swap(_M_ptr, __other._M_ptr);
    00733     _M_refcount._M_swap(__other._M_refcount);
    00734       }
    00735
    00736       template<typename _Tp1>
    00737     bool
    00738     owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const
    00739     { return _M_refcount._M_less(__rhs._M_refcount); }
    00740
    00741       template<typename _Tp1>
    00742     bool
    00743     owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const
    00744     { return _M_refcount._M_less(__rhs._M_refcount); }
    00745
    00746 #ifdef __GXX_RTTI
    00747     protected:
    00748       // This constructor is non-standard, it is used by allocate_shared.
    00749       template<typename _Alloc, typename... _Args>
    00750     __shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
    00751     : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
    00752                 std::forward<_Args>(__args)...)
    00753     {
    00754       // _M_ptr needs to point to the newly constructed object.
    00755       // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
    00756       void* __p = _M_refcount._M_get_deleter(typeid(__tag));
    00757       _M_ptr = static_cast<_Tp*>(__p);
    00758       __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
    00759     }
    00760 #else
    00761       template<typename _Alloc>
    00762         struct _Deleter
    00763         {
    00764           void operator()(_Tp* __ptr)
    00765           {
    00766             _M_alloc.destroy(__ptr);
    00767             _M_alloc.deallocate(__ptr, 1);
    00768           }
    00769           _Alloc _M_alloc;
    00770         };
    00771
    00772       template<typename _Alloc, typename... _Args>
    00773     __shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
    00774     : _M_ptr(), _M_refcount()
    00775         {
    00776       typedef typename _Alloc::template rebind<_Tp>::other _Alloc2;
    00777           _Deleter<_Alloc2> __del = { _Alloc2(__a) };
    00778           _M_ptr = __del._M_alloc.allocate(1);
    00779       __try
    00780         {
    00781               __del._M_alloc.construct(_M_ptr, std::forward<_Args>(__args)...);
    00782         }
    00783       __catch(...)
    00784         {
    00785               __del._M_alloc.deallocate(_M_ptr, 1);
    00786           __throw_exception_again;
    00787         }
    00788           __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);
    00789           _M_refcount._M_swap(__count);
    00790       __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
    00791         }
    00792 #endif
    00793
    00794       template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
    00795            typename... _Args>
    00796     friend __shared_ptr<_Tp1, _Lp1>
    00797     __allocate_shared(_Alloc __a, _Args&&... __args);
    00798
    00799     private:
    00800       void*
    00801       _M_get_deleter(const std::type_info& __ti) const
    00802       { return _M_refcount._M_get_deleter(__ti); }
    00803
    00804       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
    00805       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
    00806
    00807       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
    00808     friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
    00809
    00810       _Tp*         _M_ptr;         // Contained pointer.
    00811       __shared_count<_Lp>  _M_refcount;    // Reference counter.
    00812     };
    00813
    00814
    00815   // 20.8.13.2.7 shared_ptr comparisons
    00816   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
    00817     inline bool
    00818     operator==(const __shared_ptr<_Tp1, _Lp>& __a,
    00819            const __shared_ptr<_Tp2, _Lp>& __b)
    00820     { return __a.get() == __b.get(); }
    00821
    00822   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
    00823     inline bool
    00824     operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
    00825            const __shared_ptr<_Tp2, _Lp>& __b)
    00826     { return __a.get() != __b.get(); }
    00827
    00828   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
    00829     inline bool
    00830     operator<(const __shared_ptr<_Tp1, _Lp>& __a,
    00831           const __shared_ptr<_Tp2, _Lp>& __b)
    00832     { return __a.get() < __b.get(); }
    00833
    00834   template<typename _Sp>
    00835     struct _Sp_less : public binary_function<_Sp, _Sp, bool>
    00836     {
    00837       bool
    00838       operator()(const _Sp& __lhs, const _Sp& __rhs) const
    00839       {
    00840     typedef typename _Sp::element_type element_type;
    00841     return std::less<element_type*>()(__lhs.get(), __rhs.get());
    00842       }
    00843     };
    00844
    00845   template<typename _Tp, _Lock_policy _Lp>
    00846     struct less<__shared_ptr<_Tp, _Lp>>
    00847     : public _Sp_less<__shared_ptr<_Tp, _Lp>>
    00848     { };
    00849
    00850   // XXX LessThanComparable<_Tp> concept should provide >, >= and <=
    00851   template<typename _Tp, _Lock_policy _Lp>
    00852     inline bool
    00853     operator>(const __shared_ptr<_Tp, _Lp>& __a,
    00854           const __shared_ptr<_Tp, _Lp>& __b)
    00855     { return __a.get() > __b.get(); }
    00856
    00857   template<typename _Tp, _Lock_policy _Lp>
    00858     inline bool
    00859     operator>=(const __shared_ptr<_Tp, _Lp>& __a,
    00860            const __shared_ptr<_Tp, _Lp>& __b)
    00861     { return __a.get() >= __b.get(); }
    00862
    00863   template<typename _Tp, _Lock_policy _Lp>
    00864     inline bool
    00865     operator<=(const __shared_ptr<_Tp, _Lp>& __a,
    00866            const __shared_ptr<_Tp, _Lp>& __b)
    00867     { return __a.get() <= __b.get(); }
    00868
    00869   // 2.2.3.8 shared_ptr specialized algorithms.
    00870   template<typename _Tp, _Lock_policy _Lp>
    00871     inline void
    00872     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
    00873     { __a.swap(__b); }
    00874
    00875   // 2.2.3.9 shared_ptr casts
    00876
    00877   // The seemingly equivalent code:
    00878   // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
    00879   // will eventually result in undefined behaviour, attempting to
    00880   // delete the same object twice.
    00881   /// static_pointer_cast
    00882   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    00883     inline __shared_ptr<_Tp, _Lp>
    00884     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    00885     { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
    00886
    00887   // The seemingly equivalent code:
    00888   // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
    00889   // will eventually result in undefined behaviour, attempting to
    00890   // delete the same object twice.
    00891   /// const_pointer_cast
    00892   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    00893     inline __shared_ptr<_Tp, _Lp>
    00894     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    00895     { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
    00896
    00897   // The seemingly equivalent code:
    00898   // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
    00899   // will eventually result in undefined behaviour, attempting to
    00900   // delete the same object twice.
    00901   /// dynamic_pointer_cast
    00902   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    00903     inline __shared_ptr<_Tp, _Lp>
    00904     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    00905     {
    00906       if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
    00907     return __shared_ptr<_Tp, _Lp>(__r, __p);
    00908       return __shared_ptr<_Tp, _Lp>();
    00909     }
    00910
    00911
    00912   template<typename _Tp, _Lock_policy _Lp>
    00913     class __weak_ptr
    00914     {
    00915     public:
    00916       typedef _Tp element_type;
    00917
    00918       __weak_ptr() : _M_ptr(0), _M_refcount() // never throws
    00919       { }
    00920
    00921       // Generated copy constructor, assignment, destructor are fine.
    00922
    00923       // The "obvious" converting constructor implementation:
    00924       //
    00925       //  template<typename _Tp1>
    00926       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    00927       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    00928       //    { }
    00929       //
    00930       // has a serious problem.
    00931       //
    00932       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
    00933       //  conversion may require access to *__r._M_ptr (virtual inheritance).
    00934       //
    00935       // It is not possible to avoid spurious access violations since
    00936       // in multithreaded programs __r._M_ptr may be invalidated at any point.
    00937       template<typename _Tp1>
    00938     __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    00939     : _M_refcount(__r._M_refcount) // never throws
    00940     {
    00941       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00942       _M_ptr = __r.lock().get();
    00943     }
    00944
    00945       template<typename _Tp1>
    00946     __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
    00947     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    00948     { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
    00949
    00950       template<typename _Tp1>
    00951     __weak_ptr&
    00952     operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
    00953     {
    00954       _M_ptr = __r.lock().get();
    00955       _M_refcount = __r._M_refcount;
    00956       return *this;
    00957     }
    00958
    00959       template<typename _Tp1>
    00960     __weak_ptr&
    00961     operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
    00962     {
    00963       _M_ptr = __r._M_ptr;
    00964       _M_refcount = __r._M_refcount;
    00965       return *this;
    00966     }
    00967
    00968       __shared_ptr<_Tp, _Lp>
    00969       lock() const // never throws
    00970       {
    00971 #ifdef __GTHREADS
    00972     // Optimization: avoid throw overhead.
    00973     if (expired())
    00974       return __shared_ptr<element_type, _Lp>();
    00975
    00976     __try
    00977       {
    00978         return __shared_ptr<element_type, _Lp>(*this);
    00979       }
    00980     __catch(const bad_weak_ptr&)
    00981       {
    00982         // Q: How can we get here?
    00983         // A: Another thread may have invalidated r after the
    00984         //    use_count test above.
    00985         return __shared_ptr<element_type, _Lp>();
    00986       }
    00987
    00988 #else
    00989     // Optimization: avoid try/catch overhead when single threaded.
    00990     return expired() ? __shared_ptr<element_type, _Lp>()
    00991              : __shared_ptr<element_type, _Lp>(*this);
    00992
    00993 #endif
    00994       } // XXX MT
    00995
    00996       long
    00997       use_count() const // never throws
    00998       { return _M_refcount._M_get_use_count(); }
    00999
    01000       bool
    01001       expired() const // never throws
    01002       { return _M_refcount._M_get_use_count() == 0; }
    01003
    01004       template<typename _Tp1>
    01005     bool
    01006     owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const
    01007     { return _M_refcount._M_less(__rhs._M_refcount); }
    01008
    01009       template<typename _Tp1>
    01010     bool
    01011     owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const
    01012     { return _M_refcount._M_less(__rhs._M_refcount); }
    01013
    01014       void
    01015       reset() // never throws
    01016       { __weak_ptr().swap(*this); }
    01017
    01018       void
    01019       swap(__weak_ptr& __s) // never throws
    01020       {
    01021     std::swap(_M_ptr, __s._M_ptr);
    01022     _M_refcount._M_swap(__s._M_refcount);
    01023       }
    01024
    01025     private:
    01026       // Used by __enable_shared_from_this.
    01027       void
    01028       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
    01029       {
    01030     _M_ptr = __ptr;
    01031     _M_refcount = __refcount;
    01032       }
    01033
    01034       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
    01035       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
    01036       friend class __enable_shared_from_this<_Tp, _Lp>;
    01037       friend class enable_shared_from_this<_Tp>;
    01038
    01039       _Tp*       _M_ptr;         // Contained pointer.
    01040       __weak_count<_Lp>  _M_refcount;    // Reference counter.
    01041     };
    01042
    01043   // 20.8.13.3.7 weak_ptr specialized algorithms.
    01044   template<typename _Tp, _Lock_policy _Lp>
    01045     inline void
    01046     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
    01047     { __a.swap(__b); }
    01048
    01049   template<typename _Tp, typename _Tp1>
    01050     struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
    01051     {
    01052       bool
    01053       operator()(const _Tp& __lhs, const _Tp& __rhs) const
    01054       { return __lhs.owner_before(__rhs); }
    01055
    01056       bool
    01057       operator()(const _Tp& __lhs, const _Tp1& __rhs) const
    01058       { return __lhs.owner_before(__rhs); }
    01059
    01060       bool
    01061       operator()(const _Tp1& __lhs, const _Tp& __rhs) const
    01062       { return __lhs.owner_before(__rhs); }
    01063     };
    01064
    01065   template<typename _Tp, _Lock_policy _Lp>
    01066     struct owner_less<__shared_ptr<_Tp, _Lp>>
    01067     : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
    01068     { };
    01069
    01070   template<typename _Tp, _Lock_policy _Lp>
    01071     struct owner_less<__weak_ptr<_Tp, _Lp>>
    01072     : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
    01073     { };
    01074
    01075
    01076   template<typename _Tp, _Lock_policy _Lp>
    01077     class __enable_shared_from_this
    01078     {
    01079     protected:
    01080       __enable_shared_from_this() { }
    01081
    01082       __enable_shared_from_this(const __enable_shared_from_this&) { }
    01083
    01084       __enable_shared_from_this&
    01085       operator=(const __enable_shared_from_this&)
    01086       { return *this; }
    01087
    01088       ~__enable_shared_from_this() { }
    01089
    01090     public:
    01091       __shared_ptr<_Tp, _Lp>
    01092       shared_from_this()
    01093       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
    01094
    01095       __shared_ptr<const _Tp, _Lp>
    01096       shared_from_this() const
    01097       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
    01098
    01099     private:
    01100       template<typename _Tp1>
    01101     void
    01102     _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
    01103     { _M_weak_this._M_assign(__p, __n); }
    01104
    01105       template<typename _Tp1>
    01106     friend void
    01107     __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
    01108                      const __enable_shared_from_this* __pe,
    01109                      const _Tp1* __px)
    01110     {
    01111       if (__pe != 0)
    01112         __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
    01113     }
    01114
    01115       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
    01116     };
    01117
    01118
    01119   template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
    01120     inline __shared_ptr<_Tp, _Lp>
    01121     __allocate_shared(_Alloc __a, _Args&&... __args)
    01122     {
    01123       return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(),
    01124       std::forward<_Alloc>(__a), std::forward<_Args>(__args)...);
    01125     }
    01126
    01127   template<typename _Tp, _Lock_policy _Lp, typename... _Args>
    01128     inline __shared_ptr<_Tp, _Lp>
    01129     __make_shared(_Args&&... __args)
    01130     {
    01131       typedef typename std::remove_const<_Tp>::type _Tp_nc;
    01132       return __allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
    01133                      std::forward<_Args>(__args)...);
    01134     }
    01135
    01136 _GLIBCXX_END_NAMESPACE
    01137
    01138 #endif // _SHARED_PTR_BASE_H