# tr1/shared_ptr.h

Go to the documentation of this file.

    00001 // <tr1/shared_ptr.h> -*- 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 tr1/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 _TR1_SHARED_PTR_H
    00050 #define _TR1_SHARED_PTR_H 1
    00051
    00052 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
    00053 #  error TR1 header cannot be included from C++0x header
    00054 #endif
    00055
    00056 namespace std
    00057 {
    00058 namespace tr1
    00059 {
    00060
    00061   template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
    00062     class _Sp_counted_base_impl
    00063     : public _Sp_counted_base<_Lp>
    00064     {
    00065     public:
    00066       /**
    00067        *  @brief
    00068        *  @pre     __d(__p) must not throw.
    00069        */
    00070       _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
    00071       : _M_ptr(__p), _M_del(__d) { }
    00072
    00073       virtual void
    00074       _M_dispose() // nothrow
    00075       { _M_del(_M_ptr); }
    00076
    00077       virtual void*
    00078       _M_get_deleter(const std::type_info& __ti)
    00079       { return __ti == typeid(_Deleter) ? &_M_del : 0; }
    00080
    00081     private:
    00082       _Sp_counted_base_impl(const _Sp_counted_base_impl&);
    00083       _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
    00084
    00085       _Ptr      _M_ptr;  // copy constructor must not throw
    00086       _Deleter  _M_del;  // copy constructor must not throw
    00087     };
    00088
    00089   template<_Lock_policy _Lp = __default_lock_policy>
    00090     class __weak_count;
    00091
    00092   template<typename _Tp>
    00093     struct _Sp_deleter
    00094     {
    00095       typedef void result_type;
    00096       typedef _Tp* argument_type;
    00097       void operator()(_Tp* __p) const { delete __p; }
    00098     };
    00099
    00100   template<_Lock_policy _Lp = __default_lock_policy>
    00101     class __shared_count
    00102     {
    00103     public:
    00104       __shared_count()
    00105       : _M_pi(0) // nothrow
    00106       { }
    00107
    00108       template<typename _Ptr>
    00109         __shared_count(_Ptr __p) : _M_pi(0)
    00110         {
    00111       __try
    00112         {
    00113           typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
    00114           _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
    00115               __p, _Sp_deleter<_Tp>());
    00116         }
    00117       __catch(...)
    00118         {
    00119           delete __p;
    00120           __throw_exception_again;
    00121         }
    00122     }
    00123
    00124       template<typename _Ptr, typename _Deleter>
    00125         __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
    00126         {
    00127       __try
    00128         {
    00129           _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
    00130         }
    00131       __catch(...)
    00132         {
    00133           __d(__p); // Call _Deleter on __p.
    00134           __throw_exception_again;
    00135         }
    00136     }
    00137
    00138       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
    00139       template<typename _Tp>
    00140         explicit
    00141         __shared_count(std::auto_ptr<_Tp>& __r)
    00142     : _M_pi(new _Sp_counted_base_impl<_Tp*,
    00143         _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
    00144         { __r.release(); }
    00145
    00146       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
    00147       explicit
    00148       __shared_count(const __weak_count<_Lp>& __r);
    00149
    00150       ~__shared_count() // nothrow
    00151       {
    00152     if (_M_pi != 0)
    00153       _M_pi->_M_release();
    00154       }
    00155
    00156       __shared_count(const __shared_count& __r)
    00157       : _M_pi(__r._M_pi) // nothrow
    00158       {
    00159     if (_M_pi != 0)
    00160       _M_pi->_M_add_ref_copy();
    00161       }
    00162
    00163       __shared_count&
    00164       operator=(const __shared_count& __r) // nothrow
    00165       {
    00166     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00167     if (__tmp != _M_pi)
    00168       {
    00169         if (__tmp != 0)
    00170           __tmp->_M_add_ref_copy();
    00171         if (_M_pi != 0)
    00172           _M_pi->_M_release();
    00173         _M_pi = __tmp;
    00174       }
    00175     return *this;
    00176       }
    00177
    00178       void
    00179       _M_swap(__shared_count& __r) // nothrow
    00180       {
    00181     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00182     __r._M_pi = _M_pi;
    00183     _M_pi = __tmp;
    00184       }
    00185
    00186       long
    00187       _M_get_use_count() const // nothrow
    00188       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
    00189
    00190       bool
    00191       _M_unique() const // nothrow
    00192       { return this->_M_get_use_count() == 1; }
    00193
    00194       friend inline bool
    00195       operator==(const __shared_count& __a, const __shared_count& __b)
    00196       { return __a._M_pi == __b._M_pi; }
    00197
    00198       friend inline bool
    00199       operator<(const __shared_count& __a, const __shared_count& __b)
    00200       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
    00201
    00202       void*
    00203       _M_get_deleter(const std::type_info& __ti) const
    00204       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
    00205
    00206     private:
    00207       friend class __weak_count<_Lp>;
    00208
    00209       _Sp_counted_base<_Lp>*  _M_pi;
    00210     };
    00211
    00212
    00213   template<_Lock_policy _Lp>
    00214     class __weak_count
    00215     {
    00216     public:
    00217       __weak_count()
    00218       : _M_pi(0) // nothrow
    00219       { }
    00220
    00221       __weak_count(const __shared_count<_Lp>& __r)
    00222       : _M_pi(__r._M_pi) // nothrow
    00223       {
    00224     if (_M_pi != 0)
    00225       _M_pi->_M_weak_add_ref();
    00226       }
    00227
    00228       __weak_count(const __weak_count<_Lp>& __r)
    00229       : _M_pi(__r._M_pi) // nothrow
    00230       {
    00231     if (_M_pi != 0)
    00232       _M_pi->_M_weak_add_ref();
    00233       }
    00234
    00235       ~__weak_count() // nothrow
    00236       {
    00237     if (_M_pi != 0)
    00238       _M_pi->_M_weak_release();
    00239       }
    00240
    00241       __weak_count<_Lp>&
    00242       operator=(const __shared_count<_Lp>& __r) // nothrow
    00243       {
    00244     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00245     if (__tmp != 0)
    00246       __tmp->_M_weak_add_ref();
    00247     if (_M_pi != 0)
    00248       _M_pi->_M_weak_release();
    00249     _M_pi = __tmp;
    00250     return *this;
    00251       }
    00252
    00253       __weak_count<_Lp>&
    00254       operator=(const __weak_count<_Lp>& __r) // nothrow
    00255       {
    00256     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00257     if (__tmp != 0)
    00258       __tmp->_M_weak_add_ref();
    00259     if (_M_pi != 0)
    00260       _M_pi->_M_weak_release();
    00261     _M_pi = __tmp;
    00262     return *this;
    00263       }
    00264
    00265       void
    00266       _M_swap(__weak_count<_Lp>& __r) // nothrow
    00267       {
    00268     _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
    00269     __r._M_pi = _M_pi;
    00270     _M_pi = __tmp;
    00271       }
    00272
    00273       long
    00274       _M_get_use_count() const // nothrow
    00275       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
    00276
    00277       friend inline bool
    00278       operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
    00279       { return __a._M_pi == __b._M_pi; }
    00280
    00281       friend inline bool
    00282       operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
    00283       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
    00284
    00285     private:
    00286       friend class __shared_count<_Lp>;
    00287
    00288       _Sp_counted_base<_Lp>*  _M_pi;
    00289     };
    00290
    00291   // now that __weak_count is defined we can define this constructor:
    00292   template<_Lock_policy _Lp>
    00293     inline
    00294     __shared_count<_Lp>::
    00295     __shared_count(const __weak_count<_Lp>& __r)
    00296     : _M_pi(__r._M_pi)
    00297     {
    00298       if (_M_pi != 0)
    00299     _M_pi->_M_add_ref_lock();
    00300       else
    00301     __throw_bad_weak_ptr();
    00302     }
    00303
    00304   // Forward declarations.
    00305   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    00306     class __shared_ptr;
    00307
    00308   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    00309     class __weak_ptr;
    00310
    00311   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
    00312     class __enable_shared_from_this;
    00313
    00314   template<typename _Tp>
    00315     class shared_ptr;
    00316
    00317   template<typename _Tp>
    00318     class weak_ptr;
    00319
    00320   template<typename _Tp>
    00321     class enable_shared_from_this;
    00322
    00323   // Support for enable_shared_from_this.
    00324
    00325   // Friend of __enable_shared_from_this.
    00326   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
    00327     void
    00328     __enable_shared_from_this_helper(const __shared_count<_Lp>&,
    00329                      const __enable_shared_from_this<_Tp1,
    00330                      _Lp>*, const _Tp2*);
    00331
    00332   // Friend of enable_shared_from_this.
    00333   template<typename _Tp1, typename _Tp2>
    00334     void
    00335     __enable_shared_from_this_helper(const __shared_count<>&,
    00336                      const enable_shared_from_this<_Tp1>*,
    00337                      const _Tp2*);
    00338
    00339   template<_Lock_policy _Lp>
    00340     inline void
    00341     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
    00342     { }
    00343
    00344
    00345   struct __static_cast_tag { };
    00346   struct __const_cast_tag { };
    00347   struct __dynamic_cast_tag { };
    00348
    00349   /**
    00350    *  @class __shared_ptr
    00351    *
    00352    *  A smart pointer with reference-counted copy semantics.
    00353    *  The object pointed to is deleted when the last shared_ptr pointing to
    00354    *  it is destroyed or reset.
    00355    */
    00356   template<typename _Tp, _Lock_policy _Lp>
    00357     class __shared_ptr
    00358     {
    00359     public:
    00360       typedef _Tp   element_type;
    00361
    00362       /** @brief  Construct an empty %__shared_ptr.
    00363        *  @post   use_count()==0 && get()==0
    00364        */
    00365       __shared_ptr()
    00366       : _M_ptr(0), _M_refcount() // never throws
    00367       { }
    00368
    00369       /** @brief  Construct a %__shared_ptr that owns the pointer @a __p.
    00370        *  @param  __p  A pointer that is convertible to element_type*.
    00371        *  @post   use_count() == 1 && get() == __p
    00372        *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
    00373        */
    00374       template<typename _Tp1>
    00375         explicit
    00376         __shared_ptr(_Tp1* __p)
    00377     : _M_ptr(__p), _M_refcount(__p)
    00378         {
    00379       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00380       // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
    00381       __enable_shared_from_this_helper(_M_refcount, __p, __p);
    00382     }
    00383
    00384       //
    00385       // Requirements: _Deleter's copy constructor and destructor must
    00386       // not throw
    00387       //
    00388       // __shared_ptr will release __p by calling __d(__p)
    00389       //
    00390       /** @brief  Construct a %__shared_ptr that owns the pointer @a __p
    00391        *          and the deleter @a __d.
    00392        *  @param  __p  A pointer.
    00393        *  @param  __d  A deleter.
    00394        *  @post   use_count() == 1 && get() == __p
    00395        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
    00396        */
    00397       template<typename _Tp1, typename _Deleter>
    00398         __shared_ptr(_Tp1* __p, _Deleter __d)
    00399         : _M_ptr(__p), _M_refcount(__p, __d)
    00400         {
    00401       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00402       // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
    00403       __enable_shared_from_this_helper(_M_refcount, __p, __p);
    00404     }
    00405
    00406       //  generated copy constructor, assignment, destructor are fine.
    00407
    00408       /** @brief  If @a __r is empty, constructs an empty %__shared_ptr;
    00409        *          otherwise construct a %__shared_ptr that shares ownership
    00410        *          with @a __r.
    00411        *  @param  __r  A %__shared_ptr.
    00412        *  @post   get() == __r.get() && use_count() == __r.use_count()
    00413        */
    00414       template<typename _Tp1>
    00415         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
    00416     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    00417         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
    00418
    00419       /** @brief  Constructs a %__shared_ptr that shares ownership with @a __r
    00420        *          and stores a copy of the pointer stored in @a __r.
    00421        *  @param  __r  A weak_ptr.
    00422        *  @post   use_count() == __r.use_count()
    00423        *  @throw  bad_weak_ptr when __r.expired(),
    00424        *          in which case the constructor has no effect.
    00425        */
    00426       template<typename _Tp1>
    00427         explicit
    00428         __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    00429     : _M_refcount(__r._M_refcount) // may throw
    00430         {
    00431       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00432       // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
    00433       // did not throw.
    00434       _M_ptr = __r._M_ptr;
    00435     }
    00436
    00437 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
    00438       /**
    00439        * @post use_count() == 1 and __r.get() == 0
    00440        */
    00441       template<typename _Tp1>
    00442         explicit
    00443         __shared_ptr(std::auto_ptr<_Tp1>& __r)
    00444     : _M_ptr(__r.get()), _M_refcount()
    00445         {
    00446       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00447       // TODO requires _Tp1 is complete, delete __r.release() well-formed
    00448       _Tp1* __tmp = __r.get();
    00449       _M_refcount = __shared_count<_Lp>(__r);
    00450       __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
    00451     }
    00452
    00453 #endif
    00454
    00455       template<typename _Tp1>
    00456         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
    00457     : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
    00458       _M_refcount(__r._M_refcount)
    00459         { }
    00460
    00461       template<typename _Tp1>
    00462         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
    00463     : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
    00464       _M_refcount(__r._M_refcount)
    00465         { }
    00466
    00467       template<typename _Tp1>
    00468         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
    00469     : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
    00470       _M_refcount(__r._M_refcount)
    00471         {
    00472       if (_M_ptr == 0) // need to allocate new counter -- the cast failed
    00473         _M_refcount = __shared_count<_Lp>();
    00474     }
    00475
    00476       template<typename _Tp1>
    00477         __shared_ptr&
    00478         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
    00479         {
    00480       _M_ptr = __r._M_ptr;
    00481       _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
    00482       return *this;
    00483     }
    00484
    00485 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
    00486       template<typename _Tp1>
    00487         __shared_ptr&
    00488         operator=(std::auto_ptr<_Tp1>& __r)
    00489         {
    00490       __shared_ptr(__r).swap(*this);
    00491       return *this;
    00492     }
    00493 #endif
    00494
    00495       void
    00496       reset() // never throws
    00497       { __shared_ptr().swap(*this); }
    00498
    00499       template<typename _Tp1>
    00500         void
    00501         reset(_Tp1* __p) // _Tp1 must be complete.
    00502         {
    00503       // Catch self-reset errors.
    00504       _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
    00505       __shared_ptr(__p).swap(*this);
    00506     }
    00507
    00508       template<typename _Tp1, typename _Deleter>
    00509         void
    00510         reset(_Tp1* __p, _Deleter __d)
    00511         { __shared_ptr(__p, __d).swap(*this); }
    00512
    00513       // Allow class instantiation when _Tp is [cv-qual] void.
    00514       typename std::tr1::add_reference<_Tp>::type
    00515       operator*() const // never throws
    00516       {
    00517     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    00518     return *_M_ptr;
    00519       }
    00520
    00521       _Tp*
    00522       operator->() const // never throws
    00523       {
    00524     _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
    00525     return _M_ptr;
    00526       }
    00527
    00528       _Tp*
    00529       get() const // never throws
    00530       { return _M_ptr; }
    00531
    00532       // Implicit conversion to "bool"
    00533     private:
    00534       typedef _Tp* __shared_ptr::*__unspecified_bool_type;
    00535
    00536     public:
    00537       operator __unspecified_bool_type() const // never throws
    00538       { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
    00539
    00540       bool
    00541       unique() const // never throws
    00542       { return _M_refcount._M_unique(); }
    00543
    00544       long
    00545       use_count() const // never throws
    00546       { return _M_refcount._M_get_use_count(); }
    00547
    00548       void
    00549       swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
    00550       {
    00551     std::swap(_M_ptr, __other._M_ptr);
    00552     _M_refcount._M_swap(__other._M_refcount);
    00553       }
    00554
    00555     private:
    00556       void*
    00557       _M_get_deleter(const std::type_info& __ti) const
    00558       { return _M_refcount._M_get_deleter(__ti); }
    00559
    00560       template<typename _Tp1, _Lock_policy _Lp1>
    00561         bool
    00562         _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
    00563         { return _M_refcount < __rhs._M_refcount; }
    00564
    00565       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
    00566       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
    00567
    00568       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
    00569         friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
    00570
    00571       // Friends injected into enclosing namespace and found by ADL:
    00572       template<typename _Tp1>
    00573         friend inline bool
    00574         operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    00575         { return __a.get() == __b.get(); }
    00576
    00577       template<typename _Tp1>
    00578         friend inline bool
    00579         operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    00580         { return __a.get() != __b.get(); }
    00581
    00582       template<typename _Tp1>
    00583         friend inline bool
    00584         operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
    00585         { return __a._M_less(__b); }
    00586
    00587       _Tp*             _M_ptr;         // Contained pointer.
    00588       __shared_count<_Lp>  _M_refcount;    // Reference counter.
    00589     };
    00590
    00591   // 2.2.3.8 shared_ptr specialized algorithms.
    00592   template<typename _Tp, _Lock_policy _Lp>
    00593     inline void
    00594     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
    00595     { __a.swap(__b); }
    00596
    00597   // 2.2.3.9 shared_ptr casts
    00598   /** @warning The seemingly equivalent
    00599    *           <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
    00600    *           will eventually result in undefined behaviour,
    00601    *           attempting to delete the same object twice.
    00602    */
    00603   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    00604     inline __shared_ptr<_Tp, _Lp>
    00605     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    00606     { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
    00607
    00608   /** @warning The seemingly equivalent
    00609    *           <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
    00610    *           will eventually result in undefined behaviour,
    00611    *           attempting to delete the same object twice.
    00612    */
    00613   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    00614     inline __shared_ptr<_Tp, _Lp>
    00615     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    00616     { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
    00617
    00618   /** @warning The seemingly equivalent
    00619    *           <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
    00620    *           will eventually result in undefined behaviour,
    00621    *           attempting to delete the same object twice.
    00622    */
    00623   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
    00624     inline __shared_ptr<_Tp, _Lp>
    00625     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
    00626     { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
    00627
    00628   // 2.2.3.7 shared_ptr I/O
    00629   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
    00630     std::basic_ostream<_Ch, _Tr>&
    00631     operator<<(std::basic_ostream<_Ch, _Tr>& __os,
    00632            const __shared_ptr<_Tp, _Lp>& __p)
    00633     {
    00634       __os << __p.get();
    00635       return __os;
    00636     }
    00637
    00638   // 2.2.3.10 shared_ptr get_deleter (experimental)
    00639   template<typename _Del, typename _Tp, _Lock_policy _Lp>
    00640     inline _Del*
    00641     get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
    00642     { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
    00643
    00644
    00645   template<typename _Tp, _Lock_policy _Lp>
    00646     class __weak_ptr
    00647     {
    00648     public:
    00649       typedef _Tp element_type;
    00650
    00651       __weak_ptr()
    00652       : _M_ptr(0), _M_refcount() // never throws
    00653       { }
    00654
    00655       // Generated copy constructor, assignment, destructor are fine.
    00656
    00657       // The "obvious" converting constructor implementation:
    00658       //
    00659       //  template<typename _Tp1>
    00660       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    00661       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    00662       //    { }
    00663       //
    00664       // has a serious problem.
    00665       //
    00666       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
    00667       //  conversion may require access to *__r._M_ptr (virtual inheritance).
    00668       //
    00669       // It is not possible to avoid spurious access violations since
    00670       // in multithreaded programs __r._M_ptr may be invalidated at any point.
    00671       template<typename _Tp1>
    00672         __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
    00673     : _M_refcount(__r._M_refcount) // never throws
    00674         {
    00675       __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
    00676       _M_ptr = __r.lock().get();
    00677     }
    00678
    00679       template<typename _Tp1>
    00680         __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
    00681     : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
    00682         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
    00683
    00684       template<typename _Tp1>
    00685         __weak_ptr&
    00686         operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
    00687         {
    00688       _M_ptr = __r.lock().get();
    00689       _M_refcount = __r._M_refcount;
    00690       return *this;
    00691     }
    00692
    00693       template<typename _Tp1>
    00694         __weak_ptr&
    00695         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
    00696         {
    00697       _M_ptr = __r._M_ptr;
    00698       _M_refcount = __r._M_refcount;
    00699       return *this;
    00700     }
    00701
    00702       __shared_ptr<_Tp, _Lp>
    00703       lock() const // never throws
    00704       {
    00705 #ifdef __GTHREADS
    00706     // Optimization: avoid throw overhead.
    00707     if (expired())
    00708       return __shared_ptr<element_type, _Lp>();
    00709
    00710     __try
    00711       {
    00712         return __shared_ptr<element_type, _Lp>(*this);
    00713       }
    00714     __catch(const bad_weak_ptr&)
    00715       {
    00716         // Q: How can we get here?
    00717         // A: Another thread may have invalidated r after the
    00718         //    use_count test above.
    00719         return __shared_ptr<element_type, _Lp>();
    00720       }
    00721
    00722 #else
    00723     // Optimization: avoid try/catch overhead when single threaded.
    00724     return expired() ? __shared_ptr<element_type, _Lp>()
    00725                      : __shared_ptr<element_type, _Lp>(*this);
    00726
    00727 #endif
    00728       } // XXX MT
    00729
    00730       long
    00731       use_count() const // never throws
    00732       { return _M_refcount._M_get_use_count(); }
    00733
    00734       bool
    00735       expired() const // never throws
    00736       { return _M_refcount._M_get_use_count() == 0; }
    00737
    00738       void
    00739       reset() // never throws
    00740       { __weak_ptr().swap(*this); }
    00741
    00742       void
    00743       swap(__weak_ptr& __s) // never throws
    00744       {
    00745     std::swap(_M_ptr, __s._M_ptr);
    00746     _M_refcount._M_swap(__s._M_refcount);
    00747       }
    00748
    00749     private:
    00750       // Used by __enable_shared_from_this.
    00751       void
    00752       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
    00753       {
    00754     _M_ptr = __ptr;
    00755     _M_refcount = __refcount;
    00756       }
    00757
    00758       template<typename _Tp1>
    00759         bool
    00760         _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
    00761         { return _M_refcount < __rhs._M_refcount; }
    00762
    00763       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
    00764       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
    00765       friend class __enable_shared_from_this<_Tp, _Lp>;
    00766       friend class enable_shared_from_this<_Tp>;
    00767
    00768       // Friend injected into namespace and found by ADL.
    00769       template<typename _Tp1>
    00770         friend inline bool
    00771         operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
    00772         { return __lhs._M_less(__rhs); }
    00773
    00774       _Tp*           _M_ptr;         // Contained pointer.
    00775       __weak_count<_Lp>  _M_refcount;    // Reference counter.
    00776     };
    00777
    00778   // 2.2.4.7 weak_ptr specialized algorithms.
    00779   template<typename _Tp, _Lock_policy _Lp>
    00780     inline void
    00781     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
    00782     { __a.swap(__b); }
    00783
    00784
    00785   template<typename _Tp, _Lock_policy _Lp>
    00786     class __enable_shared_from_this
    00787     {
    00788     protected:
    00789       __enable_shared_from_this() { }
    00790
    00791       __enable_shared_from_this(const __enable_shared_from_this&) { }
    00792
    00793       __enable_shared_from_this&
    00794       operator=(const __enable_shared_from_this&)
    00795       { return *this; }
    00796
    00797       ~__enable_shared_from_this() { }
    00798
    00799     public:
    00800       __shared_ptr<_Tp, _Lp>
    00801       shared_from_this()
    00802       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
    00803
    00804       __shared_ptr<const _Tp, _Lp>
    00805       shared_from_this() const
    00806       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
    00807
    00808     private:
    00809       template<typename _Tp1>
    00810         void
    00811         _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
    00812         { _M_weak_this._M_assign(__p, __n); }
    00813
    00814       template<typename _Tp1>
    00815         friend void
    00816         __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
    00817                      const __enable_shared_from_this* __pe,
    00818                      const _Tp1* __px)
    00819         {
    00820       if (__pe != 0)
    00821         __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
    00822     }
    00823
    00824       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
    00825     };
    00826
    00827
    00828   /// shared_ptr
    00829   // The actual shared_ptr, with forwarding constructors and
    00830   // assignment operators.
    00831   template<typename _Tp>
    00832     class shared_ptr
    00833     : public __shared_ptr<_Tp>
    00834     {
    00835     public:
    00836       shared_ptr()
    00837       : __shared_ptr<_Tp>() { }
    00838
    00839       template<typename _Tp1>
    00840         explicit
    00841         shared_ptr(_Tp1* __p)
    00842     : __shared_ptr<_Tp>(__p) { }
    00843
    00844       template<typename _Tp1, typename _Deleter>
    00845         shared_ptr(_Tp1* __p, _Deleter __d)
    00846     : __shared_ptr<_Tp>(__p, __d) { }
    00847
    00848       template<typename _Tp1>
    00849         shared_ptr(const shared_ptr<_Tp1>& __r)
    00850     : __shared_ptr<_Tp>(__r) { }
    00851
    00852       template<typename _Tp1>
    00853         explicit
    00854         shared_ptr(const weak_ptr<_Tp1>& __r)
    00855     : __shared_ptr<_Tp>(__r) { }
    00856
    00857 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
    00858       template<typename _Tp1>
    00859         explicit
    00860         shared_ptr(std::auto_ptr<_Tp1>& __r)
    00861     : __shared_ptr<_Tp>(__r) { }
    00862 #endif
    00863
    00864       template<typename _Tp1>
    00865         shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
    00866     : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
    00867
    00868       template<typename _Tp1>
    00869         shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
    00870     : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
    00871
    00872       template<typename _Tp1>
    00873         shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
    00874     : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
    00875
    00876       template<typename _Tp1>
    00877         shared_ptr&
    00878         operator=(const shared_ptr<_Tp1>& __r) // never throws
    00879         {
    00880       this->__shared_ptr<_Tp>::operator=(__r);
    00881       return *this;
    00882     }
    00883
    00884 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
    00885       template<typename _Tp1>
    00886         shared_ptr&
    00887         operator=(std::auto_ptr<_Tp1>& __r)
    00888         {
    00889       this->__shared_ptr<_Tp>::operator=(__r);
    00890       return *this;
    00891     }
    00892 #endif
    00893     };
    00894
    00895   // 2.2.3.8 shared_ptr specialized algorithms.
    00896   template<typename _Tp>
    00897     inline void
    00898     swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b)
    00899     { __a.swap(__b); }
    00900
    00901   template<typename _Tp, typename _Tp1>
    00902     inline shared_ptr<_Tp>
    00903     static_pointer_cast(const shared_ptr<_Tp1>& __r)
    00904     { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
    00905
    00906   template<typename _Tp, typename _Tp1>
    00907     inline shared_ptr<_Tp>
    00908     const_pointer_cast(const shared_ptr<_Tp1>& __r)
    00909     { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
    00910
    00911   template<typename _Tp, typename _Tp1>
    00912     inline shared_ptr<_Tp>
    00913     dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
    00914     { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
    00915
    00916
    00917   /// weak_ptr
    00918   // The actual weak_ptr, with forwarding constructors and
    00919   // assignment operators.
    00920   template<typename _Tp>
    00921     class weak_ptr
    00922     : public __weak_ptr<_Tp>
    00923     {
    00924     public:
    00925       weak_ptr()
    00926       : __weak_ptr<_Tp>() { }
    00927
    00928       template<typename _Tp1>
    00929         weak_ptr(const weak_ptr<_Tp1>& __r)
    00930     : __weak_ptr<_Tp>(__r) { }
    00931
    00932       template<typename _Tp1>
    00933         weak_ptr(const shared_ptr<_Tp1>& __r)
    00934     : __weak_ptr<_Tp>(__r) { }
    00935
    00936       template<typename _Tp1>
    00937         weak_ptr&
    00938         operator=(const weak_ptr<_Tp1>& __r) // never throws
    00939         {
    00940       this->__weak_ptr<_Tp>::operator=(__r);
    00941       return *this;
    00942     }
    00943
    00944       template<typename _Tp1>
    00945         weak_ptr&
    00946         operator=(const shared_ptr<_Tp1>& __r) // never throws
    00947         {
    00948       this->__weak_ptr<_Tp>::operator=(__r);
    00949       return *this;
    00950     }
    00951
    00952       shared_ptr<_Tp>
    00953       lock() const // never throws
    00954       {
    00955 #ifdef __GTHREADS
    00956     if (this->expired())
    00957       return shared_ptr<_Tp>();
    00958
    00959     __try
    00960       {
    00961         return shared_ptr<_Tp>(*this);
    00962       }
    00963     __catch(const bad_weak_ptr&)
    00964       {
    00965         return shared_ptr<_Tp>();
    00966       }
    00967 #else
    00968     return this->expired() ? shared_ptr<_Tp>()
    00969                            : shared_ptr<_Tp>(*this);
    00970 #endif
    00971       }
    00972     };
    00973
    00974   /// enable_shared_from_this
    00975   template<typename _Tp>
    00976     class enable_shared_from_this
    00977     {
    00978     protected:
    00979       enable_shared_from_this() { }
    00980
    00981       enable_shared_from_this(const enable_shared_from_this&) { }
    00982
    00983       enable_shared_from_this&
    00984       operator=(const enable_shared_from_this&)
    00985       { return *this; }
    00986
    00987       ~enable_shared_from_this() { }
    00988
    00989     public:
    00990       shared_ptr<_Tp>
    00991       shared_from_this()
    00992       { return shared_ptr<_Tp>(this->_M_weak_this); }
    00993
    00994       shared_ptr<const _Tp>
    00995       shared_from_this() const
    00996       { return shared_ptr<const _Tp>(this->_M_weak_this); }
    00997
    00998     private:
    00999       template<typename _Tp1>
    01000         void
    01001         _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
    01002         { _M_weak_this._M_assign(__p, __n); }
    01003
    01004       template<typename _Tp1>
    01005         friend void
    01006         __enable_shared_from_this_helper(const __shared_count<>& __pn,
    01007                      const enable_shared_from_this* __pe,
    01008                      const _Tp1* __px)
    01009         {
    01010       if (__pe != 0)
    01011         __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
    01012     }
    01013
    01014       mutable weak_ptr<_Tp>  _M_weak_this;
    01015     };
    01016
    01017 }
    01018 }
    01019
    01020 #endif // _TR1_SHARED_PTR_H