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