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