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