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