bits/shared_ptr.h

Go to the documentation of this file.
00001 // shared_ptr and weak_ptr implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009 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 //  shared_count.hpp
00026 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
00027 
00028 //  shared_ptr.hpp
00029 //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
00030 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
00031 
00032 //  weak_ptr.hpp
00033 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
00034 
00035 //  enable_shared_from_this.hpp
00036 //  Copyright (C) 2002 Peter Dimov
00037 
00038 // Distributed under the Boost Software License, Version 1.0. (See
00039 // accompanying file LICENSE_1_0.txt or copy at
00040 // http://www.boost.org/LICENSE_1_0.txt)
00041 
00042 // GCC Note:  based on version 1.32.0 of the Boost library.
00043 
00044 /** @file bits/shared_ptr.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_H
00050 #define _SHARED_PTR_H 1
00051 
00052 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00053 # include <c++0x_warning.h>
00054 #endif
00055 
00056 #if defined(_GLIBCXX_INCLUDE_AS_TR1)
00057 #  error C++0x header cannot be included from TR1 header
00058 #endif
00059 
00060 _GLIBCXX_BEGIN_NAMESPACE(std)
00061 
00062   /**
00063    * @addtogroup pointer_abstractions
00064    * @{
00065    */
00066 
00067   // counted ptr with no deleter or allocator support
00068   template<typename _Ptr, _Lock_policy _Lp>
00069     class _Sp_counted_ptr
00070     : public _Sp_counted_base<_Lp>
00071     {
00072     public:
00073       _Sp_counted_ptr(_Ptr __p)
00074       : _M_ptr(__p) { }
00075     
00076       virtual void
00077       _M_dispose() // nothrow
00078       { delete _M_ptr; }
00079       
00080       virtual void
00081       _M_destroy() // nothrow
00082       { delete this; }
00083       
00084       virtual void*
00085       _M_get_deleter(const std::type_info& __ti)
00086       { return 0; }
00087       
00088       _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
00089       _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
00090       
00091     protected:
00092       _Ptr             _M_ptr;  // copy constructor must not throw
00093     };
00094 
00095   // support for custom deleter and/or allocator
00096   template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
00097     class _Sp_counted_deleter
00098     : public _Sp_counted_ptr<_Ptr, _Lp>
00099     {
00100       typedef typename _Alloc::template
00101           rebind<_Sp_counted_deleter>::other _My_alloc_type;
00102 
00103       // Helper class that stores the Deleter and also acts as an allocator.
00104       // Used to dispose of the owned pointer and the internal refcount
00105       // Requires that copies of _Alloc can free each other's memory.
00106       struct _My_Deleter
00107       : public _My_alloc_type    // copy constructor must not throw
00108       {
00109         _Deleter _M_del;         // copy constructor must not throw
00110         _My_Deleter(_Deleter __d, const _Alloc& __a)
00111           : _My_alloc_type(__a), _M_del(__d) { }
00112       };
00113 
00114     protected:
00115       typedef _Sp_counted_ptr<_Ptr, _Lp> _Base_type;
00116 
00117     public:
00118       /**
00119        *  @brief   
00120        *  @pre     __d(__p) must not throw.
00121        */
00122       _Sp_counted_deleter(_Ptr __p, _Deleter __d)
00123       : _Base_type(__p), _M_del(__d, _Alloc()) { }
00124     
00125       /**
00126        *  @brief   
00127        *  @pre     __d(__p) must not throw.
00128        */
00129       _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a)
00130       : _Base_type(__p), _M_del(__d, __a) { }
00131     
00132       virtual void
00133       _M_dispose() // nothrow
00134       { _M_del._M_del(_Base_type::_M_ptr); }
00135       
00136       virtual void
00137       _M_destroy() // nothrow
00138       {
00139         _My_alloc_type __a(_M_del);
00140         this->~_Sp_counted_deleter();
00141         __a.deallocate(this, 1);
00142       }
00143       
00144       virtual void*
00145       _M_get_deleter(const std::type_info& __ti)
00146       { return __ti == typeid(_Deleter) ? &_M_del._M_del : 0; }
00147       
00148     protected:
00149       _My_Deleter      _M_del;  // copy constructor must not throw
00150     };
00151 
00152   // helpers for make_shared / allocate_shared
00153 
00154   template<typename _Tp>
00155     struct _Sp_destroy_inplace
00156     {
00157       void operator()(_Tp* __p) const { if (__p) __p->~_Tp(); }
00158     };
00159 
00160   struct _Sp_make_shared_tag { };
00161 
00162   template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
00163     class _Sp_counted_ptr_inplace
00164     : public _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp>
00165     {
00166       typedef _Sp_counted_deleter<_Tp*, _Sp_destroy_inplace<_Tp>, _Alloc, _Lp>
00167         _Base_type;
00168 
00169     public:
00170       _Sp_counted_ptr_inplace(_Alloc __a)
00171       : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a)
00172       , _M_storage()
00173       {
00174         void* __p = &_M_storage;
00175         ::new (__p) _Tp();  // might throw
00176         _Base_type::_Base_type::_M_ptr = static_cast<_Tp*>(__p);
00177       }
00178 
00179       template<typename... _Args>
00180         _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
00181         : _Base_type(static_cast<_Tp*>(0), _Sp_destroy_inplace<_Tp>(), __a)
00182         , _M_storage()
00183         {
00184           void* __p = &_M_storage;
00185           ::new (__p) _Tp(std::forward<_Args>(__args)...);  // might throw
00186           _Base_type::_Base_type::_M_ptr = static_cast<_Tp*>(__p);
00187         }
00188 
00189       // override because the allocator needs to know the dynamic type
00190       virtual void
00191       _M_destroy() // nothrow
00192       {
00193         typedef typename _Alloc::template
00194             rebind<_Sp_counted_ptr_inplace>::other _My_alloc_type;
00195         _My_alloc_type __a(_Base_type::_M_del);
00196         this->~_Sp_counted_ptr_inplace();
00197         __a.deallocate(this, 1);
00198       }
00199 
00200       // sneaky trick so __shared_ptr can get the managed pointer
00201       virtual void*
00202       _M_get_deleter(const std::type_info& __ti)
00203       {
00204         return __ti == typeid(_Sp_make_shared_tag)
00205                ? static_cast<void*>(&_M_storage)
00206                : _Base_type::_M_get_deleter(__ti);
00207       }
00208       
00209     private:
00210       typename aligned_storage<sizeof(_Tp), alignment_of<_Tp>::value>::type
00211         _M_storage;
00212     };
00213 
00214   template<_Lock_policy _Lp = __default_lock_policy>
00215     class __weak_count;
00216 
00217   template<_Lock_policy _Lp = __default_lock_policy>
00218     class __shared_count
00219     {
00220     public: 
00221       __shared_count()
00222       : _M_pi(0) // nothrow
00223       { }
00224   
00225       template<typename _Ptr>
00226         __shared_count(_Ptr __p) : _M_pi(0)
00227         {
00228           __try
00229             {
00230               _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
00231             }
00232           __catch(...)
00233             {
00234               delete __p;
00235               __throw_exception_again;
00236             }
00237         }
00238 
00239       template<typename _Ptr, typename _Deleter>
00240         __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
00241         {
00242           // allocator's value_type doesn't matter, will rebind it anyway
00243           typedef std::allocator<int> _Alloc;
00244           typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
00245           typedef std::allocator<_Sp_cd_type> _Alloc2;
00246           _Alloc2 __a2;
00247           __try
00248             {
00249               _M_pi = __a2.allocate(1);
00250               ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d);
00251             }
00252           __catch(...)
00253             {
00254               __d(__p); // Call _Deleter on __p.
00255               if (_M_pi)
00256                 __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1);
00257               __throw_exception_again;
00258             }
00259         }
00260 
00261       template<typename _Ptr, typename _Deleter, typename _Alloc>
00262         __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
00263         {
00264           typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
00265           typedef typename _Alloc::template rebind<_Sp_cd_type>::other _Alloc2;
00266           _Alloc2 __a2(__a);
00267           __try
00268             {
00269               _M_pi = __a2.allocate(1);
00270               ::new(static_cast<void*>(_M_pi)) _Sp_cd_type(__p, __d, __a);
00271             }
00272           __catch(...)
00273             {
00274               __d(__p); // Call _Deleter on __p.
00275               if (_M_pi)
00276                 __a2.deallocate(static_cast<_Sp_cd_type*>(_M_pi), 1);
00277               __throw_exception_again;
00278             }
00279         }
00280 
00281       template<typename _Tp, typename _Alloc, typename... _Args>
00282         __shared_count(_Sp_make_shared_tag, _Tp*, _Alloc __a, _Args&&... __args)
00283         : _M_pi(0)
00284         {
00285           typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
00286           typedef typename _Alloc::template rebind<_Sp_cp_type>::other _Alloc2;
00287           _Alloc2 __a2(__a);
00288           __try
00289             {
00290               _M_pi = __a2.allocate(1);
00291               ::new(static_cast<void*>(_M_pi)) _Sp_cp_type(__a,
00292                     std::forward<_Args>(__args)...);
00293             }
00294           __catch(...)
00295             {
00296               if (_M_pi)
00297             __a2.deallocate(static_cast<_Sp_cp_type*>(_M_pi), 1);
00298               __throw_exception_again;
00299             }
00300         }
00301 
00302 #if _GLIBCXX_DEPRECATED
00303       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
00304       template<typename _Tp>
00305         explicit
00306         __shared_count(std::auto_ptr<_Tp>&& __r)
00307         : _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get()))
00308         { __r.release(); }
00309 #endif
00310 
00311       // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
00312       template<typename _Tp, typename _Del>
00313         explicit
00314         __shared_count(std::unique_ptr<_Tp, _Del>&& __r)
00315         : _M_pi(_S_create_from_up(std::move(__r)))
00316         { __r.release(); }
00317 
00318       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
00319       explicit
00320       __shared_count(const __weak_count<_Lp>& __r);
00321   
00322       ~__shared_count() // nothrow
00323       {
00324         if (_M_pi != 0)
00325           _M_pi->_M_release();
00326       }
00327 
00328       __shared_count(const __shared_count& __r)
00329       : _M_pi(__r._M_pi) // nothrow
00330       {
00331         if (_M_pi != 0)
00332           _M_pi->_M_add_ref_copy();
00333       }
00334   
00335       __shared_count&
00336       operator=(const __shared_count& __r) // nothrow
00337       {
00338         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00339         if (__tmp != _M_pi)
00340           {
00341             if (__tmp != 0)
00342               __tmp->_M_add_ref_copy();
00343             if (_M_pi != 0)
00344               _M_pi->_M_release();
00345             _M_pi = __tmp;
00346           }
00347         return *this;
00348       }
00349   
00350       void
00351       _M_swap(__shared_count& __r) // nothrow
00352       {
00353         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00354         __r._M_pi = _M_pi;
00355         _M_pi = __tmp;
00356       }
00357   
00358       long
00359       _M_get_use_count() const // nothrow
00360       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
00361 
00362       bool
00363       _M_unique() const // nothrow
00364       { return this->_M_get_use_count() == 1; }
00365 
00366       void*
00367       _M_get_deleter(const std::type_info& __ti) const
00368       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
00369 
00370       bool
00371       _M_less(const __shared_count& __rhs) const
00372       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00373 
00374       bool
00375       _M_less(const __weak_count<_Lp>& __rhs) const
00376       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00377 
00378       // friend function injected into enclosing namespace and found by ADL
00379       friend inline bool
00380       operator==(const __shared_count& __a, const __shared_count& __b)
00381       { return __a._M_pi == __b._M_pi; }
00382   
00383     private:
00384       friend class __weak_count<_Lp>;
00385 
00386       template<typename _Tp, typename _Del>
00387         static _Sp_counted_base<_Lp>*
00388         _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
00389           typename std::enable_if<!std::is_reference<_Del>::value>::type* = 0)
00390         {
00391           return new _Sp_counted_deleter<_Tp*, _Del, std::allocator<_Tp>,
00392             _Lp>(__r.get(), __r.get_deleter());
00393         }
00394 
00395       template<typename _Tp, typename _Del>
00396         static _Sp_counted_base<_Lp>*
00397         _S_create_from_up(std::unique_ptr<_Tp, _Del>&& __r,
00398           typename std::enable_if<std::is_reference<_Del>::value>::type* = 0)
00399         {
00400           typedef typename std::remove_reference<_Del>::type _Del1;
00401           typedef std::reference_wrapper<_Del1> _Del2;
00402           return new _Sp_counted_deleter<_Tp*, _Del2, std::allocator<_Tp>,
00403             _Lp>(__r.get(), std::ref(__r.get_deleter()));
00404         }
00405 
00406       _Sp_counted_base<_Lp>*  _M_pi;
00407     };
00408 
00409 
00410   template<_Lock_policy _Lp>
00411     class __weak_count
00412     {
00413     public:
00414       __weak_count()
00415       : _M_pi(0) // nothrow
00416       { }
00417   
00418       __weak_count(const __shared_count<_Lp>& __r)
00419       : _M_pi(__r._M_pi) // nothrow
00420       {
00421     if (_M_pi != 0)
00422       _M_pi->_M_weak_add_ref();
00423       }
00424       
00425       __weak_count(const __weak_count<_Lp>& __r)
00426       : _M_pi(__r._M_pi) // nothrow
00427       {
00428     if (_M_pi != 0)
00429       _M_pi->_M_weak_add_ref();
00430       }
00431       
00432       ~__weak_count() // nothrow
00433       {
00434     if (_M_pi != 0)
00435       _M_pi->_M_weak_release();
00436       }
00437       
00438       __weak_count<_Lp>&
00439       operator=(const __shared_count<_Lp>& __r) // nothrow
00440       {
00441     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00442     if (__tmp != 0)
00443       __tmp->_M_weak_add_ref();
00444     if (_M_pi != 0)
00445       _M_pi->_M_weak_release();
00446     _M_pi = __tmp;  
00447     return *this;
00448       }
00449       
00450       __weak_count<_Lp>&
00451       operator=(const __weak_count<_Lp>& __r) // nothrow
00452       {
00453     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00454     if (__tmp != 0)
00455       __tmp->_M_weak_add_ref();
00456     if (_M_pi != 0)
00457       _M_pi->_M_weak_release();
00458     _M_pi = __tmp;
00459     return *this;
00460       }
00461 
00462       void
00463       _M_swap(__weak_count<_Lp>& __r) // nothrow
00464       {
00465     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
00466     __r._M_pi = _M_pi;
00467     _M_pi = __tmp;
00468       }
00469   
00470       long
00471       _M_get_use_count() const // nothrow
00472       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
00473 
00474       bool
00475       _M_less(const __weak_count& __rhs) const
00476       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00477 
00478       bool
00479       _M_less(const __shared_count<_Lp>& __rhs) const
00480       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
00481 
00482       // friend function injected into enclosing namespace and found by ADL
00483       friend inline bool
00484       operator==(const __weak_count& __a, const __weak_count& __b)
00485       { return __a._M_pi == __b._M_pi; }
00486 
00487     private:
00488       friend class __shared_count<_Lp>;
00489 
00490       _Sp_counted_base<_Lp>*  _M_pi;
00491     };
00492 
00493   // now that __weak_count is defined we can define this constructor:
00494   template<_Lock_policy _Lp>
00495     inline
00496     __shared_count<_Lp>::
00497     __shared_count(const __weak_count<_Lp>& __r)
00498     : _M_pi(__r._M_pi)
00499     {
00500       if (_M_pi != 0)
00501     _M_pi->_M_add_ref_lock();
00502       else
00503     __throw_bad_weak_ptr();
00504     }
00505 
00506   // Forward declarations.
00507   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
00508     class __shared_ptr;
00509   
00510   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
00511     class __weak_ptr;
00512 
00513   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
00514     class __enable_shared_from_this;
00515 
00516   template<typename _Tp>
00517     class shared_ptr;
00518   
00519   template<typename _Tp>
00520     class weak_ptr;
00521 
00522   template<typename _Tp>
00523     class enable_shared_from_this;
00524 
00525   // Support for enable_shared_from_this.
00526 
00527   // Friend of __enable_shared_from_this.
00528   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
00529     void
00530     __enable_shared_from_this_helper(const __shared_count<_Lp>&,
00531                      const __enable_shared_from_this<_Tp1,
00532                      _Lp>*, const _Tp2*);
00533 
00534   // Friend of enable_shared_from_this.
00535   template<typename _Tp1, typename _Tp2>
00536     void
00537     __enable_shared_from_this_helper(const __shared_count<>&,
00538                      const enable_shared_from_this<_Tp1>*,
00539                      const _Tp2*);
00540 
00541   template<_Lock_policy _Lp>
00542     inline void
00543     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
00544     { }
00545 
00546 
00547   template<typename _Tp, _Lock_policy _Lp>
00548     class __shared_ptr
00549     {
00550     public:
00551       typedef _Tp   element_type;
00552       
00553       /** @brief  Construct an empty %__shared_ptr.
00554        *  @post   use_count()==0 && get()==0
00555        */
00556       __shared_ptr()
00557       : _M_ptr(0), _M_refcount() // never throws
00558       { }
00559 
00560       /** @brief  Construct a %__shared_ptr that owns the pointer @a __p.
00561        *  @param  __p  A pointer that is convertible to element_type*.
00562        *  @post   use_count() == 1 && get() == __p
00563        *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
00564        */
00565       template<typename _Tp1>
00566         explicit
00567         __shared_ptr(_Tp1* __p)
00568     : _M_ptr(__p), _M_refcount(__p)
00569         {
00570       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00571       // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
00572       __enable_shared_from_this_helper(_M_refcount, __p, __p);
00573     }
00574 
00575       //
00576       // Requirements: _Deleter's copy constructor and destructor must
00577       // not throw
00578       //
00579       // __shared_ptr will release __p by calling __d(__p)
00580       //
00581       /** @brief  Construct a %__shared_ptr that owns the pointer @a __p
00582        *          and the deleter @a __d.
00583        *  @param  __p  A pointer.
00584        *  @param  __d  A deleter.
00585        *  @post   use_count() == 1 && get() == __p
00586        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
00587        */
00588       template<typename _Tp1, typename _Deleter>
00589         __shared_ptr(_Tp1* __p, _Deleter __d)
00590         : _M_ptr(__p), _M_refcount(__p, __d)
00591         {
00592       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00593       // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
00594       __enable_shared_from_this_helper(_M_refcount, __p, __p);
00595     }
00596       
00597       //
00598       // Requirements: _Deleter's copy constructor and destructor must
00599       // not throw _Alloc's copy constructor and destructor must not
00600       // throw.
00601       //
00602       // __shared_ptr will release __p by calling __d(__p)
00603       //
00604       /** @brief  Construct a %__shared_ptr that owns the pointer @a __p
00605        *          and the deleter @a __d.
00606        *  @param  __p  A pointer.
00607        *  @param  __d  A deleter.
00608        *  @param  __a  An allocator.
00609        *  @post   use_count() == 1 && get() == __p
00610        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
00611        */
00612       template<typename _Tp1, typename _Deleter, typename _Alloc>
00613         __shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a)
00614     : _M_ptr(__p), _M_refcount(__p, __d, __a)
00615         {
00616       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00617       // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
00618       __enable_shared_from_this_helper(_M_refcount, __p, __p);
00619     }
00620 
00621       /** @brief  Constructs a %__shared_ptr instance that stores @a __p
00622        *          and shares ownership with @a __r.
00623        *  @param  __r  A %__shared_ptr.
00624        *  @param  __p  A pointer that will remain valid while @a *__r is valid.
00625        *  @post   get() == __p && use_count() == __r.use_count()
00626        *
00627        *  This can be used to construct a @c shared_ptr to a sub-object
00628        *  of an object managed by an existing @c shared_ptr.
00629        *
00630        * @code
00631        * shared_ptr< pair<int,int> > pii(new pair<int,int>());
00632        * shared_ptr<int> pi(pii, &pii->first);
00633        * assert(pii.use_count() == 2);
00634        * @endcode
00635        */
00636       template<typename _Tp1>
00637         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p)
00638     : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
00639         { }
00640 
00641       //  generated copy constructor, assignment, destructor are fine.
00642       
00643       /** @brief  If @a __r is empty, constructs an empty %__shared_ptr;
00644        *          otherwise construct a %__shared_ptr that shares ownership
00645        *          with @a __r.
00646        *  @param  __r  A %__shared_ptr.
00647        *  @post   get() == __r.get() && use_count() == __r.use_count()
00648        */
00649       template<typename _Tp1>
00650         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
00651     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
00652         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
00653 
00654       /** @brief  Move-constructs a %__shared_ptr instance from @a __r.
00655        *  @param  __r  A %__shared_ptr rvalue.
00656        *  @post   *this contains the old value of @a __r, @a __r is empty.
00657        */
00658       __shared_ptr(__shared_ptr&& __r)
00659       : _M_ptr(__r._M_ptr), _M_refcount() // never throws
00660       {
00661         _M_refcount._M_swap(__r._M_refcount);
00662         __r._M_ptr = 0;
00663       }
00664 
00665       /** @brief  Move-constructs a %__shared_ptr instance from @a __r.
00666        *  @param  __r  A %__shared_ptr rvalue.
00667        *  @post   *this contains the old value of @a __r, @a __r is empty.
00668        */
00669       template<typename _Tp1>
00670         __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r)
00671     : _M_ptr(__r._M_ptr), _M_refcount() // never throws
00672         {
00673           __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00674           _M_refcount._M_swap(__r._M_refcount);
00675           __r._M_ptr = 0;
00676         }
00677 
00678       /** @brief  Constructs a %__shared_ptr that shares ownership with @a __r
00679        *          and stores a copy of the pointer stored in @a __r.
00680        *  @param  __r  A weak_ptr.
00681        *  @post   use_count() == __r.use_count()
00682        *  @throw  bad_weak_ptr when __r.expired(),
00683        *          in which case the constructor has no effect.
00684        */
00685       template<typename _Tp1>
00686         explicit
00687         __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
00688     : _M_refcount(__r._M_refcount) // may throw
00689         {
00690       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00691       // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
00692       // did not throw.
00693       _M_ptr = __r._M_ptr;
00694     }
00695 
00696       template<typename _Tp1, typename _Del>
00697         explicit
00698         __shared_ptr(const std::unique_ptr<_Tp1, _Del>&) = delete;
00699 
00700       /**
00701        * If an exception is thrown this constructor has no effect.
00702        */
00703       template<typename _Tp1, typename _Del>
00704         explicit
00705         __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
00706     : _M_ptr(__r.get()), _M_refcount()
00707         {
00708       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00709       _Tp1* __tmp = __r.get();
00710       _M_refcount = __shared_count<_Lp>(std::move(__r));
00711       __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
00712     }
00713 
00714 #if _GLIBCXX_DEPRECATED
00715       /**
00716        * @post use_count() == 1 and __r.get() == 0
00717        */
00718       template<typename _Tp1>
00719         explicit
00720         __shared_ptr(std::auto_ptr<_Tp1>&& __r)
00721     : _M_ptr(__r.get()), _M_refcount()
00722         {
00723       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
00724       // TODO requires _Tp1 is complete, delete __r.release() well-formed
00725       _Tp1* __tmp = __r.get();
00726       _M_refcount = __shared_count<_Lp>(std::move(__r));
00727       __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
00728     }
00729 #endif
00730 
00731       template<typename _Tp1>
00732         __shared_ptr&
00733         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
00734         {
00735       _M_ptr = __r._M_ptr;
00736       _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
00737       return *this;
00738     }
00739 
00740 #if _GLIBCXX_DEPRECATED
00741       template<typename _Tp1>
00742         __shared_ptr&
00743         operator=(std::auto_ptr<_Tp1>&& __r)
00744         {
00745       __shared_ptr(std::move(__r)).swap(*this);
00746       return *this;
00747     }
00748 #endif
00749 
00750       __shared_ptr&
00751       operator=(__shared_ptr&& __r)
00752       {
00753         __shared_ptr(std::move(__r)).swap(*this);
00754         return *this;
00755       }
00756      
00757       template<class _Tp1>
00758         __shared_ptr&
00759         operator=(__shared_ptr<_Tp1, _Lp>&& __r)
00760         {
00761           __shared_ptr(std::move(__r)).swap(*this);
00762           return *this;
00763         }
00764 
00765       template<typename _Tp1, typename _Del>
00766         __shared_ptr&
00767         operator=(const std::unique_ptr<_Tp1, _Del>& __r) = delete;
00768 
00769       template<typename _Tp1, typename _Del>
00770         __shared_ptr&
00771         operator=(std::unique_ptr<_Tp1, _Del>&& __r)
00772         {
00773       __shared_ptr(std::move(__r)).swap(*this);
00774       return *this;
00775         }
00776 
00777       void
00778       reset() // never throws
00779       { __shared_ptr().swap(*this); }
00780 
00781       template<typename _Tp1>
00782         void
00783         reset(_Tp1* __p) // _Tp1 must be complete.
00784         {
00785       // Catch self-reset errors.
00786       _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 
00787       __shared_ptr(__p).swap(*this);
00788     }
00789 
00790       template<typename _Tp1, typename _Deleter>
00791         void
00792         reset(_Tp1* __p, _Deleter __d)
00793         { __shared_ptr(__p, __d).swap(*this); }
00794 
00795       template<typename _Tp1, typename _Deleter, typename _Alloc>
00796         void
00797         reset(_Tp1* __p, _Deleter __d, const _Alloc& __a)
00798         { __shared_ptr(__p, __d, __a).swap(*this); }
00799 
00800       // Allow class instantiation when _Tp is [cv-qual] void.
00801       typename std::add_lvalue_reference<_Tp>::type
00802       operator*() const // never throws
00803       {
00804     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00805     return *_M_ptr;
00806       }
00807 
00808       _Tp*
00809       operator->() const // never throws
00810       {
00811     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
00812     return _M_ptr;
00813       }
00814     
00815       _Tp*
00816       get() const // never throws
00817       { return _M_ptr; }
00818 
00819       // Implicit conversion to "bool"
00820     private:
00821       typedef _Tp* __shared_ptr::*__unspecified_bool_type;
00822 
00823     public:
00824       operator __unspecified_bool_type() const // never throws
00825       { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
00826 
00827       bool
00828       unique() const // never throws
00829       { return _M_refcount._M_unique(); }
00830 
00831       long
00832       use_count() const // never throws
00833       { return _M_refcount._M_get_use_count(); }
00834 
00835       void
00836       swap(__shared_ptr<_Tp, _Lp>&& __other) // never throws
00837       {
00838     std::swap(_M_ptr, __other._M_ptr);
00839     _M_refcount._M_swap(__other._M_refcount);
00840       }
00841 
00842       template<typename _Tp1>
00843         bool
00844         owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const
00845         { return _M_refcount._M_less(__rhs._M_refcount); }
00846 
00847       template<typename _Tp1>
00848         bool
00849         owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const
00850         { return _M_refcount._M_less(__rhs._M_refcount); }
00851 
00852     protected:
00853       // This constructor is non-standard, it is used by allocate_shared.
00854       template<typename _Alloc, typename... _Args>
00855         __shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
00856         : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
00857                 std::forward<_Args>(__args)...)
00858         {
00859           // _M_ptr needs to point to the newly constructed object.
00860           // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
00861           void* __p = _M_refcount._M_get_deleter(typeid(__tag));
00862           _M_ptr = static_cast<_Tp*>(__p);
00863       __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
00864         }
00865 
00866       template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
00867                typename... _Args>
00868         friend __shared_ptr<_Tp1, _Lp1>
00869         __allocate_shared(_Alloc __a, _Args&&... __args);
00870 
00871     private:
00872       void*
00873       _M_get_deleter(const std::type_info& __ti) const
00874       { return _M_refcount._M_get_deleter(__ti); }
00875 
00876       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
00877       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
00878 
00879       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
00880         friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
00881 
00882       _Tp*             _M_ptr;         // Contained pointer.
00883       __shared_count<_Lp>  _M_refcount;    // Reference counter.
00884     };
00885 
00886   // 20.8.13.2.7 shared_ptr comparisons
00887   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
00888     inline bool
00889     operator==(const __shared_ptr<_Tp1, _Lp>& __a,
00890         const __shared_ptr<_Tp2, _Lp>& __b)
00891     { return __a.get() == __b.get(); }
00892 
00893   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
00894     inline bool
00895     operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
00896         const __shared_ptr<_Tp2, _Lp>& __b)
00897     { return __a.get() != __b.get(); }
00898 
00899   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
00900     inline bool
00901     operator<(const __shared_ptr<_Tp1, _Lp>& __a,
00902         const __shared_ptr<_Tp2, _Lp>& __b)
00903     { return __a.get() < __b.get(); }
00904 
00905   template<typename _Sp>
00906     struct _Sp_less : public binary_function<_Sp, _Sp, bool>
00907     {
00908       bool
00909       operator()(const _Sp& __lhs, const _Sp& __rhs) const
00910       {
00911         return std::less<typename _Sp::element_type*>()(__lhs.get(),
00912             __rhs.get());
00913       }
00914     };
00915 
00916   template<typename _Tp, _Lock_policy _Lp>
00917     struct less<__shared_ptr<_Tp, _Lp>>
00918     : public _Sp_less<__shared_ptr<_Tp, _Lp>>
00919     { };
00920 
00921   // XXX LessThanComparable<_Tp> concept should provide >, >= and <=
00922   template<typename _Tp, _Lock_policy _Lp>
00923     inline bool
00924     operator>(const __shared_ptr<_Tp, _Lp>& __a,
00925         const __shared_ptr<_Tp, _Lp>& __b)
00926     { return __a.get() > __b.get(); }
00927 
00928   template<typename _Tp, _Lock_policy _Lp>
00929     inline bool
00930     operator>=(const __shared_ptr<_Tp, _Lp>& __a,
00931         const __shared_ptr<_Tp, _Lp>& __b)
00932     { return __a.get() >= __b.get(); }
00933 
00934   template<typename _Tp, _Lock_policy _Lp>
00935     inline bool
00936     operator<=(const __shared_ptr<_Tp, _Lp>& __a,
00937         const __shared_ptr<_Tp, _Lp>& __b)
00938     { return __a.get() <= __b.get(); }
00939 
00940   // 2.2.3.8 shared_ptr specialized algorithms.
00941   template<typename _Tp, _Lock_policy _Lp>
00942     inline void
00943     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
00944     { __a.swap(__b); }
00945 
00946   template<typename _Tp, _Lock_policy _Lp>
00947     inline void
00948     swap(__shared_ptr<_Tp, _Lp>&& __a, __shared_ptr<_Tp, _Lp>& __b)
00949     { __a.swap(__b); }
00950 
00951   template<typename _Tp, _Lock_policy _Lp>
00952     inline void
00953     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>&& __b)
00954     { __a.swap(__b); }
00955 
00956   // 2.2.3.9 shared_ptr casts
00957   /** @warning The seemingly equivalent
00958    *           <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
00959    *           will eventually result in undefined behaviour,
00960    *           attempting to delete the same object twice.
00961    */
00962   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
00963     inline __shared_ptr<_Tp, _Lp>
00964     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
00965     { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
00966 
00967   /** @warning The seemingly equivalent
00968    *           <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
00969    *           will eventually result in undefined behaviour,
00970    *           attempting to delete the same object twice.
00971    */
00972   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
00973     inline __shared_ptr<_Tp, _Lp>
00974     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
00975     { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
00976 
00977   /** @warning The seemingly equivalent
00978    *           <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
00979    *           will eventually result in undefined behaviour,
00980    *           attempting to delete the same object twice.
00981    */
00982   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
00983     inline __shared_ptr<_Tp, _Lp>
00984     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
00985     {
00986       if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
00987         return __shared_ptr<_Tp, _Lp>(__r, __p);
00988       return __shared_ptr<_Tp, _Lp>();
00989     }
00990 
00991   // 2.2.3.7 shared_ptr I/O
00992   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
00993     std::basic_ostream<_Ch, _Tr>&
00994     operator<<(std::basic_ostream<_Ch, _Tr>& __os, 
00995            const __shared_ptr<_Tp, _Lp>& __p)
00996     {
00997       __os << __p.get();
00998       return __os;
00999     }
01000 
01001   // 2.2.3.10 shared_ptr get_deleter (experimental)
01002   template<typename _Del, typename _Tp, _Lock_policy _Lp>
01003     inline _Del*
01004     get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
01005     { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
01006 
01007 
01008   template<typename _Tp, _Lock_policy _Lp>
01009     class __weak_ptr
01010     {
01011     public:
01012       typedef _Tp element_type;
01013       
01014       __weak_ptr()
01015       : _M_ptr(0), _M_refcount() // never throws
01016       { }
01017 
01018       // Generated copy constructor, assignment, destructor are fine.
01019       
01020       // The "obvious" converting constructor implementation:
01021       //
01022       //  template<typename _Tp1>
01023       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
01024       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
01025       //    { }
01026       //
01027       // has a serious problem.
01028       //
01029       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
01030       //  conversion may require access to *__r._M_ptr (virtual inheritance).
01031       //
01032       // It is not possible to avoid spurious access violations since
01033       // in multithreaded programs __r._M_ptr may be invalidated at any point.
01034       template<typename _Tp1>
01035         __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
01036     : _M_refcount(__r._M_refcount) // never throws
01037         {
01038       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
01039       _M_ptr = __r.lock().get();
01040     }
01041 
01042       template<typename _Tp1>
01043         __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
01044     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
01045         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
01046 
01047       template<typename _Tp1>
01048         __weak_ptr&
01049         operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
01050         {
01051       _M_ptr = __r.lock().get();
01052       _M_refcount = __r._M_refcount;
01053       return *this;
01054     }
01055       
01056       template<typename _Tp1>
01057         __weak_ptr&
01058         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
01059         {
01060       _M_ptr = __r._M_ptr;
01061       _M_refcount = __r._M_refcount;
01062       return *this;
01063     }
01064 
01065       __shared_ptr<_Tp, _Lp>
01066       lock() const // never throws
01067       {
01068 #ifdef __GTHREADS
01069     // Optimization: avoid throw overhead.
01070     if (expired())
01071       return __shared_ptr<element_type, _Lp>();
01072 
01073     __try
01074       {
01075         return __shared_ptr<element_type, _Lp>(*this);
01076       }
01077     __catch(const bad_weak_ptr&)
01078       {
01079         // Q: How can we get here?
01080         // A: Another thread may have invalidated r after the
01081         //    use_count test above.
01082         return __shared_ptr<element_type, _Lp>();
01083       }
01084     
01085 #else
01086     // Optimization: avoid try/catch overhead when single threaded.
01087     return expired() ? __shared_ptr<element_type, _Lp>()
01088                      : __shared_ptr<element_type, _Lp>(*this);
01089 
01090 #endif
01091       } // XXX MT
01092 
01093       long
01094       use_count() const // never throws
01095       { return _M_refcount._M_get_use_count(); }
01096 
01097       bool
01098       expired() const // never throws
01099       { return _M_refcount._M_get_use_count() == 0; }
01100 
01101       template<typename _Tp1>
01102         bool
01103         owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const
01104         { return _M_refcount._M_less(__rhs._M_refcount); }
01105 
01106       template<typename _Tp1>
01107         bool
01108         owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const
01109         { return _M_refcount._M_less(__rhs._M_refcount); }
01110 
01111       void
01112       reset() // never throws
01113       { __weak_ptr().swap(*this); }
01114 
01115       void
01116       swap(__weak_ptr& __s) // never throws
01117       {
01118     std::swap(_M_ptr, __s._M_ptr);
01119     _M_refcount._M_swap(__s._M_refcount);
01120       }
01121 
01122       // comparisons
01123       template<typename _Tp1>
01124         bool operator<(const __weak_ptr<_Tp1, _Lp>&) const = delete;
01125       template<typename _Tp1>
01126         bool operator<=(const __weak_ptr<_Tp1, _Lp>&) const = delete;
01127       template<typename _Tp1>
01128         bool operator>(const __weak_ptr<_Tp1, _Lp>&) const = delete;
01129       template<typename _Tp1>
01130         bool operator>=(const __weak_ptr<_Tp1, _Lp>&) const = delete;
01131 
01132     private:
01133       // Used by __enable_shared_from_this.
01134       void
01135       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
01136       {
01137     _M_ptr = __ptr;
01138     _M_refcount = __refcount;
01139       }
01140 
01141       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
01142       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
01143       friend class __enable_shared_from_this<_Tp, _Lp>;
01144       friend class enable_shared_from_this<_Tp>;
01145 
01146       _Tp*           _M_ptr;         // Contained pointer.
01147       __weak_count<_Lp>  _M_refcount;    // Reference counter.
01148     };
01149 
01150   // 20.8.13.3.7 weak_ptr specialized algorithms.
01151   template<typename _Tp, _Lock_policy _Lp>
01152     inline void
01153     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
01154     { __a.swap(__b); }
01155 
01156   /// owner_less
01157   template<typename _Tp> struct owner_less;
01158 
01159   template<typename _Tp, typename _Tp1>
01160     struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
01161     {
01162       bool
01163       operator()(const _Tp& __lhs, const _Tp& __rhs) const
01164       { return __lhs.owner_before(__rhs); }
01165       bool
01166       operator()(const _Tp& __lhs, const _Tp1& __rhs) const
01167       { return __lhs.owner_before(__rhs); }
01168       bool
01169       operator()(const _Tp1& __lhs, const _Tp& __rhs) const
01170       { return __lhs.owner_before(__rhs); }
01171     };
01172 
01173   template<typename _Tp, _Lock_policy _Lp>
01174     struct owner_less<__shared_ptr<_Tp, _Lp>>
01175     : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
01176     { };
01177 
01178   template<typename _Tp, _Lock_policy _Lp>
01179     struct owner_less<__weak_ptr<_Tp, _Lp>>
01180     : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
01181     {
01182     };
01183 
01184 
01185   template<typename _Tp, _Lock_policy _Lp>
01186     class __enable_shared_from_this
01187     {
01188     protected:
01189       __enable_shared_from_this() { }
01190       
01191       __enable_shared_from_this(const __enable_shared_from_this&) { }
01192       
01193       __enable_shared_from_this&
01194       operator=(const __enable_shared_from_this&)
01195       { return *this; }
01196 
01197       ~__enable_shared_from_this() { }
01198       
01199     public:
01200       __shared_ptr<_Tp, _Lp>
01201       shared_from_this()
01202       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
01203 
01204       __shared_ptr<const _Tp, _Lp>
01205       shared_from_this() const
01206       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
01207 
01208     private:
01209       template<typename _Tp1>
01210         void
01211         _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
01212         { _M_weak_this._M_assign(__p, __n); }
01213 
01214       template<typename _Tp1>
01215         friend void
01216         __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
01217                      const __enable_shared_from_this* __pe,
01218                      const _Tp1* __px)
01219         {
01220       if (__pe != 0)
01221         __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
01222     }
01223 
01224       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
01225     };
01226 
01227   /**
01228    *  @brief A smart pointer with reference-counted copy semantics. 
01229    *  
01230    *  The object pointed to is deleted when the last shared_ptr pointing to
01231    *  it is destroyed or reset.
01232    */
01233   template<typename _Tp>
01234     class shared_ptr
01235     : public __shared_ptr<_Tp>
01236     {
01237     public:
01238       shared_ptr()
01239       : __shared_ptr<_Tp>() { }
01240 
01241       template<typename _Tp1>
01242         explicit
01243         shared_ptr(_Tp1* __p)
01244     : __shared_ptr<_Tp>(__p) { }
01245 
01246       template<typename _Tp1, typename _Deleter>
01247         shared_ptr(_Tp1* __p, _Deleter __d)
01248     : __shared_ptr<_Tp>(__p, __d) { }
01249 
01250       template<typename _Tp1, typename _Deleter, typename _Alloc>
01251         shared_ptr(_Tp1* __p, _Deleter __d, const _Alloc& __a)
01252     : __shared_ptr<_Tp>(__p, __d, __a) { }
01253 
01254       // Aliasing constructor
01255       template<typename _Tp1>
01256         shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p)
01257     : __shared_ptr<_Tp>(__r, __p) { }
01258 
01259       template<typename _Tp1>
01260         shared_ptr(const shared_ptr<_Tp1>& __r)
01261     : __shared_ptr<_Tp>(__r) { }
01262 
01263       shared_ptr(shared_ptr&& __r)
01264       : __shared_ptr<_Tp>(std::move(__r)) { }
01265 
01266       template<typename _Tp1>
01267         shared_ptr(shared_ptr<_Tp1>&& __r)
01268         : __shared_ptr<_Tp>(std::move(__r)) { }
01269 
01270       template<typename _Tp1>
01271         explicit
01272         shared_ptr(const weak_ptr<_Tp1>& __r)
01273     : __shared_ptr<_Tp>(__r) { }
01274 
01275 #if _GLIBCXX_DEPRECATED
01276       template<typename _Tp1>
01277         explicit
01278         shared_ptr(std::auto_ptr<_Tp1>&& __r)
01279     : __shared_ptr<_Tp>(std::move(__r)) { }
01280 #endif
01281 
01282       template<typename _Tp1, typename _Del>
01283         explicit
01284         shared_ptr(const std::unique_ptr<_Tp1, _Del>&) = delete;
01285 
01286       template<typename _Tp1, typename _Del>
01287         explicit
01288         shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
01289     : __shared_ptr<_Tp>(std::move(__r)) { }
01290 
01291       template<typename _Tp1>
01292         shared_ptr&
01293         operator=(const shared_ptr<_Tp1>& __r) // never throws
01294         {
01295       this->__shared_ptr<_Tp>::operator=(__r);
01296       return *this;
01297     }
01298 
01299 #if _GLIBCXX_DEPRECATED
01300       template<typename _Tp1>
01301         shared_ptr&
01302         operator=(std::auto_ptr<_Tp1>&& __r)
01303         {
01304       this->__shared_ptr<_Tp>::operator=(std::move(__r));
01305       return *this;
01306     }
01307 #endif
01308 
01309       shared_ptr&
01310       operator=(shared_ptr&& __r)
01311       {
01312         this->__shared_ptr<_Tp>::operator=(std::move(__r));
01313         return *this;
01314       }
01315      
01316       template<class _Tp1>
01317         shared_ptr&
01318         operator=(shared_ptr<_Tp1>&& __r)
01319         {
01320           this->__shared_ptr<_Tp>::operator=(std::move(__r));
01321           return *this;
01322         }
01323 
01324       template<typename _Tp1, typename _Del>
01325         shared_ptr&
01326         operator=(const std::unique_ptr<_Tp1, _Del>& __r) = delete;
01327 
01328       template<typename _Tp1, typename _Del>
01329         shared_ptr&
01330         operator=(std::unique_ptr<_Tp1, _Del>&& __r)
01331         {
01332       this->__shared_ptr<_Tp>::operator=(std::move(__r));
01333       return *this;
01334     }
01335 
01336     private:
01337       // This constructor is non-standard, it is used by allocate_shared.
01338       template<typename _Alloc, typename... _Args>
01339         shared_ptr(_Sp_make_shared_tag __tag, _Alloc __a, _Args&&... __args)
01340         : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
01341         { }
01342 
01343       template<typename _Tp1, typename _Alloc, typename... _Args>
01344         friend shared_ptr<_Tp1>
01345         allocate_shared(_Alloc __a, _Args&&... __args);
01346     };
01347 
01348   // 20.8.13.2.7 shared_ptr comparisons
01349   template<typename _Tp1, typename _Tp2>
01350     inline bool
01351     operator==(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b)
01352     { return __a.get() == __b.get(); }
01353 
01354   template<typename _Tp1, typename _Tp2>
01355     inline bool
01356     operator!=(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b)
01357     { return __a.get() != __b.get(); }
01358 
01359   template<typename _Tp1, typename _Tp2>
01360     inline bool
01361     operator<(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b)
01362     { return __a.get() < __b.get(); }
01363 
01364   template<typename _Tp>
01365     struct less<shared_ptr<_Tp>>
01366     : public _Sp_less<shared_ptr<_Tp>>
01367     { };
01368 
01369   // 20.8.13.2.9 shared_ptr specialized algorithms.
01370   template<typename _Tp>
01371     inline void
01372     swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b)
01373     { __a.swap(__b); }
01374 
01375   template<typename _Tp>
01376     inline void
01377     swap(shared_ptr<_Tp>&& __a, shared_ptr<_Tp>& __b)
01378     { __a.swap(__b); }
01379 
01380   template<typename _Tp>
01381     inline void
01382     swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>&& __b)
01383     { __a.swap(__b); }
01384 
01385   // 20.8.13.2.10 shared_ptr casts.
01386   template<typename _Tp, typename _Tp1>
01387     inline shared_ptr<_Tp>
01388     static_pointer_cast(const shared_ptr<_Tp1>& __r)
01389     { return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); }
01390 
01391   template<typename _Tp, typename _Tp1>
01392     inline shared_ptr<_Tp>
01393     const_pointer_cast(const shared_ptr<_Tp1>& __r)
01394     { return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); }
01395 
01396   template<typename _Tp, typename _Tp1>
01397     inline shared_ptr<_Tp>
01398     dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
01399     {
01400       if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
01401         return shared_ptr<_Tp>(__r, __p);
01402       return shared_ptr<_Tp>();
01403     }
01404 
01405 
01406   /** 
01407    *  @brief A smart pointer with weak semantics.
01408    *  
01409    *  With forwarding constructors and assignment operators.
01410    */
01411   template<typename _Tp>
01412     class weak_ptr
01413     : public __weak_ptr<_Tp>
01414     {
01415     public:
01416       weak_ptr()
01417       : __weak_ptr<_Tp>() { }
01418       
01419       template<typename _Tp1>
01420         weak_ptr(const weak_ptr<_Tp1>& __r)
01421     : __weak_ptr<_Tp>(__r) { }
01422 
01423       template<typename _Tp1>
01424         weak_ptr(const shared_ptr<_Tp1>& __r)
01425     : __weak_ptr<_Tp>(__r) { }
01426 
01427       template<typename _Tp1>
01428         weak_ptr&
01429         operator=(const weak_ptr<_Tp1>& __r) // never throws
01430         {
01431       this->__weak_ptr<_Tp>::operator=(__r);
01432       return *this;
01433     }
01434 
01435       template<typename _Tp1>
01436         weak_ptr&
01437         operator=(const shared_ptr<_Tp1>& __r) // never throws
01438         {
01439       this->__weak_ptr<_Tp>::operator=(__r);
01440       return *this;
01441     }
01442 
01443       shared_ptr<_Tp>
01444       lock() const // never throws
01445       {
01446 #ifdef __GTHREADS
01447     if (this->expired())
01448       return shared_ptr<_Tp>();
01449 
01450     __try
01451       {
01452         return shared_ptr<_Tp>(*this);
01453       }
01454     __catch(const bad_weak_ptr&)
01455       {
01456         return shared_ptr<_Tp>();
01457       }
01458 #else
01459     return this->expired() ? shared_ptr<_Tp>()
01460                            : shared_ptr<_Tp>(*this);
01461 #endif
01462       }
01463 
01464       // comparisons
01465       template<typename _Tp1>
01466         bool operator<(const weak_ptr<_Tp1>&) const = delete;
01467       template<typename _Tp1>
01468         bool operator<=(const weak_ptr<_Tp1>&) const = delete;
01469       template<typename _Tp1>
01470         bool operator>(const weak_ptr<_Tp1>&) const = delete;
01471       template<typename _Tp1>
01472         bool operator>=(const weak_ptr<_Tp1>&) const = delete;
01473     };
01474 
01475   // 20.8.13.3.7 weak_ptr specialized algorithms.
01476   template<typename _Tp>
01477     inline void
01478     swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b)
01479     { __a.swap(__b); }
01480 
01481   /// owner_less
01482   template<typename _Tp>
01483     struct owner_less<shared_ptr<_Tp>>
01484     : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
01485     { };
01486 
01487   template<typename _Tp>
01488     struct owner_less<weak_ptr<_Tp>>
01489     : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
01490     { };
01491 
01492   /** 
01493    *  @brief Base class allowing use of member function shared_from_this.
01494    */
01495   template<typename _Tp>
01496     class enable_shared_from_this
01497     {
01498     protected:
01499       enable_shared_from_this() { }
01500       
01501       enable_shared_from_this(const enable_shared_from_this&) { }
01502 
01503       enable_shared_from_this&
01504       operator=(const enable_shared_from_this&)
01505       { return *this; }
01506 
01507       ~enable_shared_from_this() { }
01508 
01509     public:
01510       shared_ptr<_Tp>
01511       shared_from_this()
01512       { return shared_ptr<_Tp>(this->_M_weak_this); }
01513 
01514       shared_ptr<const _Tp>
01515       shared_from_this() const
01516       { return shared_ptr<const _Tp>(this->_M_weak_this); }
01517 
01518     private:
01519       template<typename _Tp1>
01520         void
01521         _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
01522         { _M_weak_this._M_assign(__p, __n); }
01523 
01524       template<typename _Tp1>
01525         friend void
01526         __enable_shared_from_this_helper(const __shared_count<>& __pn,
01527                      const enable_shared_from_this* __pe,
01528                      const _Tp1* __px)
01529         {
01530       if (__pe != 0)
01531         __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
01532     }
01533 
01534       mutable weak_ptr<_Tp>  _M_weak_this;
01535     };
01536 
01537   template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
01538     inline __shared_ptr<_Tp, _Lp>
01539     __allocate_shared(_Alloc __a, _Args&&... __args)
01540     {
01541       return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(),
01542           std::forward<_Alloc>(__a), std::forward<_Args>(__args)...);
01543     }
01544 
01545   template<typename _Tp, _Lock_policy _Lp, typename... _Args>
01546     inline __shared_ptr<_Tp, _Lp>
01547     __make_shared(_Args&&... __args)
01548     {
01549       typedef typename std::remove_const<_Tp>::type _Tp_nc;
01550       return __allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
01551               std::forward<_Args>(__args)...);
01552     }
01553 
01554   /** @brief  Create an object that is owned by a shared_ptr.
01555    *  @param  __a     An allocator.
01556    *  @param  __args  Arguments for the @a _Tp object's constructor.
01557    *  @return A shared_ptr that owns the newly created object.
01558    *  @throw  An exception thrown from @a _Alloc::allocate or from the
01559    *          constructor of @a _Tp.
01560    *
01561    *  A copy of @a __a will be used to allocate memory for the shared_ptr
01562    *  and the new object.
01563    */
01564   template<typename _Tp, typename _Alloc, typename... _Args>
01565     inline shared_ptr<_Tp>
01566     allocate_shared(_Alloc __a, _Args&&... __args)
01567     {
01568       return shared_ptr<_Tp>(_Sp_make_shared_tag(), std::forward<_Alloc>(__a),
01569               std::forward<_Args>(__args)...);
01570     }
01571 
01572   /** @brief  Create an object that is owned by a shared_ptr. 
01573    *  @param  __args  Arguments for the @a _Tp object's constructor.
01574    *  @return A shared_ptr that owns the newly created object.
01575    *  @throw  std::bad_alloc, or an exception thrown from the
01576    *          constructor of @a _Tp.
01577    */
01578   template<typename _Tp, typename... _Args>
01579     inline shared_ptr<_Tp>
01580     make_shared(_Args&&... __args)
01581     {
01582       typedef typename std::remove_const<_Tp>::type _Tp_nc;
01583       return allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
01584               std::forward<_Args>(__args)...);
01585     }
01586 
01587   // @} group pointer_abstractions
01588 
01589 _GLIBCXX_END_NAMESPACE
01590 
01591 #endif // _SHARED_PTR_H

Generated on Thu Jul 23 21:16:16 2009 for libstdc++ by  doxygen 1.5.8