libstdc++

shared_ptr_base.h

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