xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr_base.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj // shared_ptr and weak_ptr implementation details -*- C++ -*-
2*38fd1498Szrj 
3*38fd1498Szrj // Copyright (C) 2007-2018 Free Software Foundation, Inc.
4*38fd1498Szrj //
5*38fd1498Szrj // This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj // software; you can redistribute it and/or modify it under the
7*38fd1498Szrj // terms of the GNU General Public License as published by the
8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj // any later version.
10*38fd1498Szrj 
11*38fd1498Szrj // This library is distributed in the hope that it will be useful,
12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj // GNU General Public License for more details.
15*38fd1498Szrj 
16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj // 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj 
20*38fd1498Szrj // You should have received a copy of the GNU General Public License and
21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj // <http://www.gnu.org/licenses/>.
24*38fd1498Szrj 
25*38fd1498Szrj // GCC Note: Based on files from version 1.32.0 of the Boost library.
26*38fd1498Szrj 
27*38fd1498Szrj //  shared_count.hpp
28*38fd1498Szrj //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
29*38fd1498Szrj 
30*38fd1498Szrj //  shared_ptr.hpp
31*38fd1498Szrj //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
32*38fd1498Szrj //  Copyright (C) 2001, 2002, 2003 Peter Dimov
33*38fd1498Szrj 
34*38fd1498Szrj //  weak_ptr.hpp
35*38fd1498Szrj //  Copyright (C) 2001, 2002, 2003 Peter Dimov
36*38fd1498Szrj 
37*38fd1498Szrj //  enable_shared_from_this.hpp
38*38fd1498Szrj //  Copyright (C) 2002 Peter Dimov
39*38fd1498Szrj 
40*38fd1498Szrj // Distributed under the Boost Software License, Version 1.0. (See
41*38fd1498Szrj // accompanying file LICENSE_1_0.txt or copy at
42*38fd1498Szrj // http://www.boost.org/LICENSE_1_0.txt)
43*38fd1498Szrj 
44*38fd1498Szrj /** @file bits/shared_ptr_base.h
45*38fd1498Szrj  *  This is an internal header file, included by other library headers.
46*38fd1498Szrj  *  Do not attempt to use it directly. @headername{memory}
47*38fd1498Szrj  */
48*38fd1498Szrj 
49*38fd1498Szrj #ifndef _SHARED_PTR_BASE_H
50*38fd1498Szrj #define _SHARED_PTR_BASE_H 1
51*38fd1498Szrj 
52*38fd1498Szrj #if __cpp_rtti
53*38fd1498Szrj # include <typeinfo>
54*38fd1498Szrj #endif
55*38fd1498Szrj #include <bits/allocated_ptr.h>
56*38fd1498Szrj #include <bits/refwrap.h>
57*38fd1498Szrj #include <bits/stl_function.h>
58*38fd1498Szrj #include <ext/aligned_buffer.h>
59*38fd1498Szrj 
60*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
61*38fd1498Szrj {
62*38fd1498Szrj #if !__cpp_rtti
63*38fd1498Szrj   class type_info;
64*38fd1498Szrj #endif
65*38fd1498Szrj 
66*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
67*38fd1498Szrj 
68*38fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
69*38fd1498Szrj #pragma GCC diagnostic push
70*38fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
71*38fd1498Szrj   template<typename> class auto_ptr;
72*38fd1498Szrj #pragma GCC diagnostic pop
73*38fd1498Szrj #endif
74*38fd1498Szrj 
75*38fd1498Szrj  /**
76*38fd1498Szrj    *  @brief  Exception possibly thrown by @c shared_ptr.
77*38fd1498Szrj    *  @ingroup exceptions
78*38fd1498Szrj    */
79*38fd1498Szrj   class bad_weak_ptr : public std::exception
80*38fd1498Szrj   {
81*38fd1498Szrj   public:
82*38fd1498Szrj     virtual char const* what() const noexcept;
83*38fd1498Szrj 
84*38fd1498Szrj     virtual ~bad_weak_ptr() noexcept;
85*38fd1498Szrj   };
86*38fd1498Szrj 
87*38fd1498Szrj   // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
88*38fd1498Szrj   inline void
89*38fd1498Szrj   __throw_bad_weak_ptr()
90*38fd1498Szrj   { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
91*38fd1498Szrj 
92*38fd1498Szrj   using __gnu_cxx::_Lock_policy;
93*38fd1498Szrj   using __gnu_cxx::__default_lock_policy;
94*38fd1498Szrj   using __gnu_cxx::_S_single;
95*38fd1498Szrj   using __gnu_cxx::_S_mutex;
96*38fd1498Szrj   using __gnu_cxx::_S_atomic;
97*38fd1498Szrj 
98*38fd1498Szrj   // Empty helper class except when the template argument is _S_mutex.
99*38fd1498Szrj   template<_Lock_policy _Lp>
100*38fd1498Szrj     class _Mutex_base
101*38fd1498Szrj     {
102*38fd1498Szrj     protected:
103*38fd1498Szrj       // The atomic policy uses fully-fenced builtins, single doesn't care.
104*38fd1498Szrj       enum { _S_need_barriers = 0 };
105*38fd1498Szrj     };
106*38fd1498Szrj 
107*38fd1498Szrj   template<>
108*38fd1498Szrj     class _Mutex_base<_S_mutex>
109*38fd1498Szrj     : public __gnu_cxx::__mutex
110*38fd1498Szrj     {
111*38fd1498Szrj     protected:
112*38fd1498Szrj       // This policy is used when atomic builtins are not available.
113*38fd1498Szrj       // The replacement atomic operations might not have the necessary
114*38fd1498Szrj       // memory barriers.
115*38fd1498Szrj       enum { _S_need_barriers = 1 };
116*38fd1498Szrj     };
117*38fd1498Szrj 
118*38fd1498Szrj   template<_Lock_policy _Lp = __default_lock_policy>
119*38fd1498Szrj     class _Sp_counted_base
120*38fd1498Szrj     : public _Mutex_base<_Lp>
121*38fd1498Szrj     {
122*38fd1498Szrj     public:
123*38fd1498Szrj       _Sp_counted_base() noexcept
124*38fd1498Szrj       : _M_use_count(1), _M_weak_count(1) { }
125*38fd1498Szrj 
126*38fd1498Szrj       virtual
127*38fd1498Szrj       ~_Sp_counted_base() noexcept
128*38fd1498Szrj       { }
129*38fd1498Szrj 
130*38fd1498Szrj       // Called when _M_use_count drops to zero, to release the resources
131*38fd1498Szrj       // managed by *this.
132*38fd1498Szrj       virtual void
133*38fd1498Szrj       _M_dispose() noexcept = 0;
134*38fd1498Szrj 
135*38fd1498Szrj       // Called when _M_weak_count drops to zero.
136*38fd1498Szrj       virtual void
137*38fd1498Szrj       _M_destroy() noexcept
138*38fd1498Szrj       { delete this; }
139*38fd1498Szrj 
140*38fd1498Szrj       virtual void*
141*38fd1498Szrj       _M_get_deleter(const std::type_info&) noexcept = 0;
142*38fd1498Szrj 
143*38fd1498Szrj       void
144*38fd1498Szrj       _M_add_ref_copy()
145*38fd1498Szrj       { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
146*38fd1498Szrj 
147*38fd1498Szrj       void
148*38fd1498Szrj       _M_add_ref_lock();
149*38fd1498Szrj 
150*38fd1498Szrj       bool
151*38fd1498Szrj       _M_add_ref_lock_nothrow();
152*38fd1498Szrj 
153*38fd1498Szrj       void
154*38fd1498Szrj       _M_release() noexcept
155*38fd1498Szrj       {
156*38fd1498Szrj         // Be race-detector-friendly.  For more info see bits/c++config.
157*38fd1498Szrj         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
158*38fd1498Szrj 	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
159*38fd1498Szrj 	  {
160*38fd1498Szrj             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
161*38fd1498Szrj 	    _M_dispose();
162*38fd1498Szrj 	    // There must be a memory barrier between dispose() and destroy()
163*38fd1498Szrj 	    // to ensure that the effects of dispose() are observed in the
164*38fd1498Szrj 	    // thread that runs destroy().
165*38fd1498Szrj 	    // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
166*38fd1498Szrj 	    if (_Mutex_base<_Lp>::_S_need_barriers)
167*38fd1498Szrj 	      {
168*38fd1498Szrj 		__atomic_thread_fence (__ATOMIC_ACQ_REL);
169*38fd1498Szrj 	      }
170*38fd1498Szrj 
171*38fd1498Szrj             // Be race-detector-friendly.  For more info see bits/c++config.
172*38fd1498Szrj             _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
173*38fd1498Szrj 	    if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
174*38fd1498Szrj 						       -1) == 1)
175*38fd1498Szrj               {
176*38fd1498Szrj                 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
177*38fd1498Szrj 	        _M_destroy();
178*38fd1498Szrj               }
179*38fd1498Szrj 	  }
180*38fd1498Szrj       }
181*38fd1498Szrj 
182*38fd1498Szrj       void
183*38fd1498Szrj       _M_weak_add_ref() noexcept
184*38fd1498Szrj       { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
185*38fd1498Szrj 
186*38fd1498Szrj       void
187*38fd1498Szrj       _M_weak_release() noexcept
188*38fd1498Szrj       {
189*38fd1498Szrj         // Be race-detector-friendly. For more info see bits/c++config.
190*38fd1498Szrj         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
191*38fd1498Szrj 	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
192*38fd1498Szrj 	  {
193*38fd1498Szrj             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
194*38fd1498Szrj 	    if (_Mutex_base<_Lp>::_S_need_barriers)
195*38fd1498Szrj 	      {
196*38fd1498Szrj 	        // See _M_release(),
197*38fd1498Szrj 	        // destroy() must observe results of dispose()
198*38fd1498Szrj 		__atomic_thread_fence (__ATOMIC_ACQ_REL);
199*38fd1498Szrj 	      }
200*38fd1498Szrj 	    _M_destroy();
201*38fd1498Szrj 	  }
202*38fd1498Szrj       }
203*38fd1498Szrj 
204*38fd1498Szrj       long
205*38fd1498Szrj       _M_get_use_count() const noexcept
206*38fd1498Szrj       {
207*38fd1498Szrj         // No memory barrier is used here so there is no synchronization
208*38fd1498Szrj         // with other threads.
209*38fd1498Szrj         return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
210*38fd1498Szrj       }
211*38fd1498Szrj 
212*38fd1498Szrj     private:
213*38fd1498Szrj       _Sp_counted_base(_Sp_counted_base const&) = delete;
214*38fd1498Szrj       _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
215*38fd1498Szrj 
216*38fd1498Szrj       _Atomic_word  _M_use_count;     // #shared
217*38fd1498Szrj       _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
218*38fd1498Szrj     };
219*38fd1498Szrj 
220*38fd1498Szrj   template<>
221*38fd1498Szrj     inline void
222*38fd1498Szrj     _Sp_counted_base<_S_single>::
223*38fd1498Szrj     _M_add_ref_lock()
224*38fd1498Szrj     {
225*38fd1498Szrj       if (_M_use_count == 0)
226*38fd1498Szrj 	__throw_bad_weak_ptr();
227*38fd1498Szrj       ++_M_use_count;
228*38fd1498Szrj     }
229*38fd1498Szrj 
230*38fd1498Szrj   template<>
231*38fd1498Szrj     inline void
232*38fd1498Szrj     _Sp_counted_base<_S_mutex>::
233*38fd1498Szrj     _M_add_ref_lock()
234*38fd1498Szrj     {
235*38fd1498Szrj       __gnu_cxx::__scoped_lock sentry(*this);
236*38fd1498Szrj       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
237*38fd1498Szrj 	{
238*38fd1498Szrj 	  _M_use_count = 0;
239*38fd1498Szrj 	  __throw_bad_weak_ptr();
240*38fd1498Szrj 	}
241*38fd1498Szrj     }
242*38fd1498Szrj 
243*38fd1498Szrj   template<>
244*38fd1498Szrj     inline void
245*38fd1498Szrj     _Sp_counted_base<_S_atomic>::
246*38fd1498Szrj     _M_add_ref_lock()
247*38fd1498Szrj     {
248*38fd1498Szrj       // Perform lock-free add-if-not-zero operation.
249*38fd1498Szrj       _Atomic_word __count = _M_get_use_count();
250*38fd1498Szrj       do
251*38fd1498Szrj 	{
252*38fd1498Szrj 	  if (__count == 0)
253*38fd1498Szrj 	    __throw_bad_weak_ptr();
254*38fd1498Szrj 	  // Replace the current counter value with the old value + 1, as
255*38fd1498Szrj 	  // long as it's not changed meanwhile.
256*38fd1498Szrj 	}
257*38fd1498Szrj       while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
258*38fd1498Szrj 					  true, __ATOMIC_ACQ_REL,
259*38fd1498Szrj 					  __ATOMIC_RELAXED));
260*38fd1498Szrj     }
261*38fd1498Szrj 
262*38fd1498Szrj   template<>
263*38fd1498Szrj     inline bool
264*38fd1498Szrj     _Sp_counted_base<_S_single>::
265*38fd1498Szrj     _M_add_ref_lock_nothrow()
266*38fd1498Szrj     {
267*38fd1498Szrj       if (_M_use_count == 0)
268*38fd1498Szrj 	return false;
269*38fd1498Szrj       ++_M_use_count;
270*38fd1498Szrj       return true;
271*38fd1498Szrj     }
272*38fd1498Szrj 
273*38fd1498Szrj   template<>
274*38fd1498Szrj     inline bool
275*38fd1498Szrj     _Sp_counted_base<_S_mutex>::
276*38fd1498Szrj     _M_add_ref_lock_nothrow()
277*38fd1498Szrj     {
278*38fd1498Szrj       __gnu_cxx::__scoped_lock sentry(*this);
279*38fd1498Szrj       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
280*38fd1498Szrj 	{
281*38fd1498Szrj 	  _M_use_count = 0;
282*38fd1498Szrj 	  return false;
283*38fd1498Szrj 	}
284*38fd1498Szrj       return true;
285*38fd1498Szrj     }
286*38fd1498Szrj 
287*38fd1498Szrj   template<>
288*38fd1498Szrj     inline bool
289*38fd1498Szrj     _Sp_counted_base<_S_atomic>::
290*38fd1498Szrj     _M_add_ref_lock_nothrow()
291*38fd1498Szrj     {
292*38fd1498Szrj       // Perform lock-free add-if-not-zero operation.
293*38fd1498Szrj       _Atomic_word __count = _M_get_use_count();
294*38fd1498Szrj       do
295*38fd1498Szrj 	{
296*38fd1498Szrj 	  if (__count == 0)
297*38fd1498Szrj 	    return false;
298*38fd1498Szrj 	  // Replace the current counter value with the old value + 1, as
299*38fd1498Szrj 	  // long as it's not changed meanwhile.
300*38fd1498Szrj 	}
301*38fd1498Szrj       while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
302*38fd1498Szrj 					  true, __ATOMIC_ACQ_REL,
303*38fd1498Szrj 					  __ATOMIC_RELAXED));
304*38fd1498Szrj       return true;
305*38fd1498Szrj     }
306*38fd1498Szrj 
307*38fd1498Szrj   template<>
308*38fd1498Szrj     inline void
309*38fd1498Szrj     _Sp_counted_base<_S_single>::_M_add_ref_copy()
310*38fd1498Szrj     { ++_M_use_count; }
311*38fd1498Szrj 
312*38fd1498Szrj   template<>
313*38fd1498Szrj     inline void
314*38fd1498Szrj     _Sp_counted_base<_S_single>::_M_release() noexcept
315*38fd1498Szrj     {
316*38fd1498Szrj       if (--_M_use_count == 0)
317*38fd1498Szrj         {
318*38fd1498Szrj           _M_dispose();
319*38fd1498Szrj           if (--_M_weak_count == 0)
320*38fd1498Szrj             _M_destroy();
321*38fd1498Szrj         }
322*38fd1498Szrj     }
323*38fd1498Szrj 
324*38fd1498Szrj   template<>
325*38fd1498Szrj     inline void
326*38fd1498Szrj     _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept
327*38fd1498Szrj     { ++_M_weak_count; }
328*38fd1498Szrj 
329*38fd1498Szrj   template<>
330*38fd1498Szrj     inline void
331*38fd1498Szrj     _Sp_counted_base<_S_single>::_M_weak_release() noexcept
332*38fd1498Szrj     {
333*38fd1498Szrj       if (--_M_weak_count == 0)
334*38fd1498Szrj         _M_destroy();
335*38fd1498Szrj     }
336*38fd1498Szrj 
337*38fd1498Szrj   template<>
338*38fd1498Szrj     inline long
339*38fd1498Szrj     _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept
340*38fd1498Szrj     { return _M_use_count; }
341*38fd1498Szrj 
342*38fd1498Szrj 
343*38fd1498Szrj   // Forward declarations.
344*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
345*38fd1498Szrj     class __shared_ptr;
346*38fd1498Szrj 
347*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
348*38fd1498Szrj     class __weak_ptr;
349*38fd1498Szrj 
350*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
351*38fd1498Szrj     class __enable_shared_from_this;
352*38fd1498Szrj 
353*38fd1498Szrj   template<typename _Tp>
354*38fd1498Szrj     class shared_ptr;
355*38fd1498Szrj 
356*38fd1498Szrj   template<typename _Tp>
357*38fd1498Szrj     class weak_ptr;
358*38fd1498Szrj 
359*38fd1498Szrj   template<typename _Tp>
360*38fd1498Szrj     struct owner_less;
361*38fd1498Szrj 
362*38fd1498Szrj   template<typename _Tp>
363*38fd1498Szrj     class enable_shared_from_this;
364*38fd1498Szrj 
365*38fd1498Szrj   template<_Lock_policy _Lp = __default_lock_policy>
366*38fd1498Szrj     class __weak_count;
367*38fd1498Szrj 
368*38fd1498Szrj   template<_Lock_policy _Lp = __default_lock_policy>
369*38fd1498Szrj     class __shared_count;
370*38fd1498Szrj 
371*38fd1498Szrj 
372*38fd1498Szrj   // Counted ptr with no deleter or allocator support
373*38fd1498Szrj   template<typename _Ptr, _Lock_policy _Lp>
374*38fd1498Szrj     class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
375*38fd1498Szrj     {
376*38fd1498Szrj     public:
377*38fd1498Szrj       explicit
378*38fd1498Szrj       _Sp_counted_ptr(_Ptr __p) noexcept
379*38fd1498Szrj       : _M_ptr(__p) { }
380*38fd1498Szrj 
381*38fd1498Szrj       virtual void
382*38fd1498Szrj       _M_dispose() noexcept
383*38fd1498Szrj       { delete _M_ptr; }
384*38fd1498Szrj 
385*38fd1498Szrj       virtual void
386*38fd1498Szrj       _M_destroy() noexcept
387*38fd1498Szrj       { delete this; }
388*38fd1498Szrj 
389*38fd1498Szrj       virtual void*
390*38fd1498Szrj       _M_get_deleter(const std::type_info&) noexcept
391*38fd1498Szrj       { return nullptr; }
392*38fd1498Szrj 
393*38fd1498Szrj       _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
394*38fd1498Szrj       _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
395*38fd1498Szrj 
396*38fd1498Szrj     private:
397*38fd1498Szrj       _Ptr             _M_ptr;
398*38fd1498Szrj     };
399*38fd1498Szrj 
400*38fd1498Szrj   template<>
401*38fd1498Szrj     inline void
402*38fd1498Szrj     _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { }
403*38fd1498Szrj 
404*38fd1498Szrj   template<>
405*38fd1498Szrj     inline void
406*38fd1498Szrj     _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { }
407*38fd1498Szrj 
408*38fd1498Szrj   template<>
409*38fd1498Szrj     inline void
410*38fd1498Szrj     _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { }
411*38fd1498Szrj 
412*38fd1498Szrj   template<int _Nm, typename _Tp,
413*38fd1498Szrj 	   bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
414*38fd1498Szrj     struct _Sp_ebo_helper;
415*38fd1498Szrj 
416*38fd1498Szrj   /// Specialization using EBO.
417*38fd1498Szrj   template<int _Nm, typename _Tp>
418*38fd1498Szrj     struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp
419*38fd1498Szrj     {
420*38fd1498Szrj       explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { }
421*38fd1498Szrj       explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { }
422*38fd1498Szrj 
423*38fd1498Szrj       static _Tp&
424*38fd1498Szrj       _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); }
425*38fd1498Szrj     };
426*38fd1498Szrj 
427*38fd1498Szrj   /// Specialization not using EBO.
428*38fd1498Szrj   template<int _Nm, typename _Tp>
429*38fd1498Szrj     struct _Sp_ebo_helper<_Nm, _Tp, false>
430*38fd1498Szrj     {
431*38fd1498Szrj       explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { }
432*38fd1498Szrj       explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(std::move(__tp)) { }
433*38fd1498Szrj 
434*38fd1498Szrj       static _Tp&
435*38fd1498Szrj       _S_get(_Sp_ebo_helper& __eboh)
436*38fd1498Szrj       { return __eboh._M_tp; }
437*38fd1498Szrj 
438*38fd1498Szrj     private:
439*38fd1498Szrj       _Tp _M_tp;
440*38fd1498Szrj     };
441*38fd1498Szrj 
442*38fd1498Szrj   // Support for custom deleter and/or allocator
443*38fd1498Szrj   template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
444*38fd1498Szrj     class _Sp_counted_deleter final : public _Sp_counted_base<_Lp>
445*38fd1498Szrj     {
446*38fd1498Szrj       class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc>
447*38fd1498Szrj       {
448*38fd1498Szrj 	typedef _Sp_ebo_helper<0, _Deleter>	_Del_base;
449*38fd1498Szrj 	typedef _Sp_ebo_helper<1, _Alloc>	_Alloc_base;
450*38fd1498Szrj 
451*38fd1498Szrj       public:
452*38fd1498Szrj 	_Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
453*38fd1498Szrj 	: _M_ptr(__p), _Del_base(std::move(__d)), _Alloc_base(__a)
454*38fd1498Szrj 	{ }
455*38fd1498Szrj 
456*38fd1498Szrj 	_Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); }
457*38fd1498Szrj 	_Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); }
458*38fd1498Szrj 
459*38fd1498Szrj 	_Ptr _M_ptr;
460*38fd1498Szrj       };
461*38fd1498Szrj 
462*38fd1498Szrj     public:
463*38fd1498Szrj       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>;
464*38fd1498Szrj 
465*38fd1498Szrj       // __d(__p) must not throw.
466*38fd1498Szrj       _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
467*38fd1498Szrj       : _M_impl(__p, std::move(__d), _Alloc()) { }
468*38fd1498Szrj 
469*38fd1498Szrj       // __d(__p) must not throw.
470*38fd1498Szrj       _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
471*38fd1498Szrj       : _M_impl(__p, std::move(__d), __a) { }
472*38fd1498Szrj 
473*38fd1498Szrj       ~_Sp_counted_deleter() noexcept { }
474*38fd1498Szrj 
475*38fd1498Szrj       virtual void
476*38fd1498Szrj       _M_dispose() noexcept
477*38fd1498Szrj       { _M_impl._M_del()(_M_impl._M_ptr); }
478*38fd1498Szrj 
479*38fd1498Szrj       virtual void
480*38fd1498Szrj       _M_destroy() noexcept
481*38fd1498Szrj       {
482*38fd1498Szrj 	__allocator_type __a(_M_impl._M_alloc());
483*38fd1498Szrj 	__allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
484*38fd1498Szrj 	this->~_Sp_counted_deleter();
485*38fd1498Szrj       }
486*38fd1498Szrj 
487*38fd1498Szrj       virtual void*
488*38fd1498Szrj       _M_get_deleter(const std::type_info& __ti) noexcept
489*38fd1498Szrj       {
490*38fd1498Szrj #if __cpp_rtti
491*38fd1498Szrj 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
492*38fd1498Szrj 	// 2400. shared_ptr's get_deleter() should use addressof()
493*38fd1498Szrj         return __ti == typeid(_Deleter)
494*38fd1498Szrj 	  ? std::__addressof(_M_impl._M_del())
495*38fd1498Szrj 	  : nullptr;
496*38fd1498Szrj #else
497*38fd1498Szrj         return nullptr;
498*38fd1498Szrj #endif
499*38fd1498Szrj       }
500*38fd1498Szrj 
501*38fd1498Szrj     private:
502*38fd1498Szrj       _Impl _M_impl;
503*38fd1498Szrj     };
504*38fd1498Szrj 
505*38fd1498Szrj   // helpers for make_shared / allocate_shared
506*38fd1498Szrj 
507*38fd1498Szrj   struct _Sp_make_shared_tag
508*38fd1498Szrj   {
509*38fd1498Szrj #if !__cpp_rtti
510*38fd1498Szrj   private:
511*38fd1498Szrj     template<typename _Tp, _Lock_policy _Lp>
512*38fd1498Szrj       friend class __shared_ptr;
513*38fd1498Szrj     template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
514*38fd1498Szrj       friend class _Sp_counted_ptr_inplace;
515*38fd1498Szrj 
516*38fd1498Szrj     static const type_info&
517*38fd1498Szrj     _S_ti() noexcept
518*38fd1498Szrj     {
519*38fd1498Szrj       static constexpr _Sp_make_shared_tag __tag;
520*38fd1498Szrj       return reinterpret_cast<const type_info&>(__tag);
521*38fd1498Szrj     }
522*38fd1498Szrj #endif
523*38fd1498Szrj   };
524*38fd1498Szrj 
525*38fd1498Szrj   template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
526*38fd1498Szrj     class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
527*38fd1498Szrj     {
528*38fd1498Szrj       class _Impl : _Sp_ebo_helper<0, _Alloc>
529*38fd1498Szrj       {
530*38fd1498Szrj 	typedef _Sp_ebo_helper<0, _Alloc>	_A_base;
531*38fd1498Szrj 
532*38fd1498Szrj       public:
533*38fd1498Szrj 	explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { }
534*38fd1498Szrj 
535*38fd1498Szrj 	_Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); }
536*38fd1498Szrj 
537*38fd1498Szrj 	__gnu_cxx::__aligned_buffer<_Tp> _M_storage;
538*38fd1498Szrj       };
539*38fd1498Szrj 
540*38fd1498Szrj     public:
541*38fd1498Szrj       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
542*38fd1498Szrj 
543*38fd1498Szrj       template<typename... _Args>
544*38fd1498Szrj 	_Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
545*38fd1498Szrj 	: _M_impl(__a)
546*38fd1498Szrj 	{
547*38fd1498Szrj 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
548*38fd1498Szrj 	  // 2070.  allocate_shared should use allocator_traits<A>::construct
549*38fd1498Szrj 	  allocator_traits<_Alloc>::construct(__a, _M_ptr(),
550*38fd1498Szrj 	      std::forward<_Args>(__args)...); // might throw
551*38fd1498Szrj 	}
552*38fd1498Szrj 
553*38fd1498Szrj       ~_Sp_counted_ptr_inplace() noexcept { }
554*38fd1498Szrj 
555*38fd1498Szrj       virtual void
556*38fd1498Szrj       _M_dispose() noexcept
557*38fd1498Szrj       {
558*38fd1498Szrj 	allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
559*38fd1498Szrj       }
560*38fd1498Szrj 
561*38fd1498Szrj       // Override because the allocator needs to know the dynamic type
562*38fd1498Szrj       virtual void
563*38fd1498Szrj       _M_destroy() noexcept
564*38fd1498Szrj       {
565*38fd1498Szrj 	__allocator_type __a(_M_impl._M_alloc());
566*38fd1498Szrj 	__allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
567*38fd1498Szrj 	this->~_Sp_counted_ptr_inplace();
568*38fd1498Szrj       }
569*38fd1498Szrj 
570*38fd1498Szrj       // Sneaky trick so __shared_ptr can get the managed pointer
571*38fd1498Szrj       virtual void*
572*38fd1498Szrj       _M_get_deleter(const std::type_info& __ti) noexcept
573*38fd1498Szrj       {
574*38fd1498Szrj #if __cpp_rtti
575*38fd1498Szrj 	if (__ti == typeid(_Sp_make_shared_tag))
576*38fd1498Szrj #else
577*38fd1498Szrj 	if (&__ti == &_Sp_make_shared_tag::_S_ti())
578*38fd1498Szrj #endif
579*38fd1498Szrj 	  return const_cast<typename remove_cv<_Tp>::type*>(_M_ptr());
580*38fd1498Szrj 	return nullptr;
581*38fd1498Szrj       }
582*38fd1498Szrj 
583*38fd1498Szrj     private:
584*38fd1498Szrj       _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
585*38fd1498Szrj 
586*38fd1498Szrj       _Impl _M_impl;
587*38fd1498Szrj     };
588*38fd1498Szrj 
589*38fd1498Szrj   // The default deleter for shared_ptr<T[]> and shared_ptr<T[N]>.
590*38fd1498Szrj   struct __sp_array_delete
591*38fd1498Szrj   {
592*38fd1498Szrj     template<typename _Yp>
593*38fd1498Szrj       void operator()(_Yp* __p) const { delete[] __p; }
594*38fd1498Szrj   };
595*38fd1498Szrj 
596*38fd1498Szrj   template<_Lock_policy _Lp>
597*38fd1498Szrj     class __shared_count
598*38fd1498Szrj     {
599*38fd1498Szrj     public:
600*38fd1498Szrj       constexpr __shared_count() noexcept : _M_pi(0)
601*38fd1498Szrj       { }
602*38fd1498Szrj 
603*38fd1498Szrj       template<typename _Ptr>
604*38fd1498Szrj         explicit
605*38fd1498Szrj 	__shared_count(_Ptr __p) : _M_pi(0)
606*38fd1498Szrj 	{
607*38fd1498Szrj 	  __try
608*38fd1498Szrj 	    {
609*38fd1498Szrj 	      _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
610*38fd1498Szrj 	    }
611*38fd1498Szrj 	  __catch(...)
612*38fd1498Szrj 	    {
613*38fd1498Szrj 	      delete __p;
614*38fd1498Szrj 	      __throw_exception_again;
615*38fd1498Szrj 	    }
616*38fd1498Szrj 	}
617*38fd1498Szrj 
618*38fd1498Szrj       template<typename _Ptr>
619*38fd1498Szrj 	__shared_count(_Ptr __p, /* is_array = */ false_type)
620*38fd1498Szrj 	: __shared_count(__p)
621*38fd1498Szrj 	{ }
622*38fd1498Szrj 
623*38fd1498Szrj       template<typename _Ptr>
624*38fd1498Szrj 	__shared_count(_Ptr __p, /* is_array = */ true_type)
625*38fd1498Szrj 	: __shared_count(__p, __sp_array_delete{}, allocator<void>())
626*38fd1498Szrj 	{ }
627*38fd1498Szrj 
628*38fd1498Szrj       template<typename _Ptr, typename _Deleter>
629*38fd1498Szrj 	__shared_count(_Ptr __p, _Deleter __d)
630*38fd1498Szrj 	: __shared_count(__p, std::move(__d), allocator<void>())
631*38fd1498Szrj 	{ }
632*38fd1498Szrj 
633*38fd1498Szrj       template<typename _Ptr, typename _Deleter, typename _Alloc>
634*38fd1498Szrj 	__shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
635*38fd1498Szrj 	{
636*38fd1498Szrj 	  typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
637*38fd1498Szrj 	  __try
638*38fd1498Szrj 	    {
639*38fd1498Szrj 	      typename _Sp_cd_type::__allocator_type __a2(__a);
640*38fd1498Szrj 	      auto __guard = std::__allocate_guarded(__a2);
641*38fd1498Szrj 	      _Sp_cd_type* __mem = __guard.get();
642*38fd1498Szrj 	      ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a));
643*38fd1498Szrj 	      _M_pi = __mem;
644*38fd1498Szrj 	      __guard = nullptr;
645*38fd1498Szrj 	    }
646*38fd1498Szrj 	  __catch(...)
647*38fd1498Szrj 	    {
648*38fd1498Szrj 	      __d(__p); // Call _Deleter on __p.
649*38fd1498Szrj 	      __throw_exception_again;
650*38fd1498Szrj 	    }
651*38fd1498Szrj 	}
652*38fd1498Szrj 
653*38fd1498Szrj       template<typename _Tp, typename _Alloc, typename... _Args>
654*38fd1498Szrj 	__shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a,
655*38fd1498Szrj 		       _Args&&... __args)
656*38fd1498Szrj 	: _M_pi(0)
657*38fd1498Szrj 	{
658*38fd1498Szrj 	  typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
659*38fd1498Szrj 	  typename _Sp_cp_type::__allocator_type __a2(__a);
660*38fd1498Szrj 	  auto __guard = std::__allocate_guarded(__a2);
661*38fd1498Szrj 	  _Sp_cp_type* __mem = __guard.get();
662*38fd1498Szrj 	  ::new (__mem) _Sp_cp_type(std::move(__a),
663*38fd1498Szrj 				    std::forward<_Args>(__args)...);
664*38fd1498Szrj 	  _M_pi = __mem;
665*38fd1498Szrj 	  __guard = nullptr;
666*38fd1498Szrj 	}
667*38fd1498Szrj 
668*38fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
669*38fd1498Szrj #pragma GCC diagnostic push
670*38fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
671*38fd1498Szrj       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
672*38fd1498Szrj       template<typename _Tp>
673*38fd1498Szrj         explicit
674*38fd1498Szrj 	__shared_count(std::auto_ptr<_Tp>&& __r);
675*38fd1498Szrj #pragma GCC diagnostic pop
676*38fd1498Szrj #endif
677*38fd1498Szrj 
678*38fd1498Szrj       // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
679*38fd1498Szrj       template<typename _Tp, typename _Del>
680*38fd1498Szrj         explicit
681*38fd1498Szrj 	__shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
682*38fd1498Szrj 	{
683*38fd1498Szrj 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
684*38fd1498Szrj 	  // 2415. Inconsistency between unique_ptr and shared_ptr
685*38fd1498Szrj 	  if (__r.get() == nullptr)
686*38fd1498Szrj 	    return;
687*38fd1498Szrj 
688*38fd1498Szrj 	  using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
689*38fd1498Szrj 	  using _Del2 = typename conditional<is_reference<_Del>::value,
690*38fd1498Szrj 	      reference_wrapper<typename remove_reference<_Del>::type>,
691*38fd1498Szrj 	      _Del>::type;
692*38fd1498Szrj 	  using _Sp_cd_type
693*38fd1498Szrj 	    = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
694*38fd1498Szrj 	  using _Alloc = allocator<_Sp_cd_type>;
695*38fd1498Szrj 	  using _Alloc_traits = allocator_traits<_Alloc>;
696*38fd1498Szrj 	  _Alloc __a;
697*38fd1498Szrj 	  _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
698*38fd1498Szrj 	  _Alloc_traits::construct(__a, __mem, __r.release(),
699*38fd1498Szrj 				   __r.get_deleter());  // non-throwing
700*38fd1498Szrj 	  _M_pi = __mem;
701*38fd1498Szrj 	}
702*38fd1498Szrj 
703*38fd1498Szrj       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
704*38fd1498Szrj       explicit __shared_count(const __weak_count<_Lp>& __r);
705*38fd1498Szrj 
706*38fd1498Szrj       // Does not throw if __r._M_get_use_count() == 0, caller must check.
707*38fd1498Szrj       explicit __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t);
708*38fd1498Szrj 
709*38fd1498Szrj       ~__shared_count() noexcept
710*38fd1498Szrj       {
711*38fd1498Szrj 	if (_M_pi != nullptr)
712*38fd1498Szrj 	  _M_pi->_M_release();
713*38fd1498Szrj       }
714*38fd1498Szrj 
715*38fd1498Szrj       __shared_count(const __shared_count& __r) noexcept
716*38fd1498Szrj       : _M_pi(__r._M_pi)
717*38fd1498Szrj       {
718*38fd1498Szrj 	if (_M_pi != 0)
719*38fd1498Szrj 	  _M_pi->_M_add_ref_copy();
720*38fd1498Szrj       }
721*38fd1498Szrj 
722*38fd1498Szrj       __shared_count&
723*38fd1498Szrj       operator=(const __shared_count& __r) noexcept
724*38fd1498Szrj       {
725*38fd1498Szrj 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
726*38fd1498Szrj 	if (__tmp != _M_pi)
727*38fd1498Szrj 	  {
728*38fd1498Szrj 	    if (__tmp != 0)
729*38fd1498Szrj 	      __tmp->_M_add_ref_copy();
730*38fd1498Szrj 	    if (_M_pi != 0)
731*38fd1498Szrj 	      _M_pi->_M_release();
732*38fd1498Szrj 	    _M_pi = __tmp;
733*38fd1498Szrj 	  }
734*38fd1498Szrj 	return *this;
735*38fd1498Szrj       }
736*38fd1498Szrj 
737*38fd1498Szrj       void
738*38fd1498Szrj       _M_swap(__shared_count& __r) noexcept
739*38fd1498Szrj       {
740*38fd1498Szrj 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
741*38fd1498Szrj 	__r._M_pi = _M_pi;
742*38fd1498Szrj 	_M_pi = __tmp;
743*38fd1498Szrj       }
744*38fd1498Szrj 
745*38fd1498Szrj       long
746*38fd1498Szrj       _M_get_use_count() const noexcept
747*38fd1498Szrj       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
748*38fd1498Szrj 
749*38fd1498Szrj       bool
750*38fd1498Szrj       _M_unique() const noexcept
751*38fd1498Szrj       { return this->_M_get_use_count() == 1; }
752*38fd1498Szrj 
753*38fd1498Szrj       void*
754*38fd1498Szrj       _M_get_deleter(const std::type_info& __ti) const noexcept
755*38fd1498Szrj       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; }
756*38fd1498Szrj 
757*38fd1498Szrj       bool
758*38fd1498Szrj       _M_less(const __shared_count& __rhs) const noexcept
759*38fd1498Szrj       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
760*38fd1498Szrj 
761*38fd1498Szrj       bool
762*38fd1498Szrj       _M_less(const __weak_count<_Lp>& __rhs) const noexcept
763*38fd1498Szrj       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
764*38fd1498Szrj 
765*38fd1498Szrj       // Friend function injected into enclosing namespace and found by ADL
766*38fd1498Szrj       friend inline bool
767*38fd1498Szrj       operator==(const __shared_count& __a, const __shared_count& __b) noexcept
768*38fd1498Szrj       { return __a._M_pi == __b._M_pi; }
769*38fd1498Szrj 
770*38fd1498Szrj     private:
771*38fd1498Szrj       friend class __weak_count<_Lp>;
772*38fd1498Szrj 
773*38fd1498Szrj       _Sp_counted_base<_Lp>*  _M_pi;
774*38fd1498Szrj     };
775*38fd1498Szrj 
776*38fd1498Szrj 
777*38fd1498Szrj   template<_Lock_policy _Lp>
778*38fd1498Szrj     class __weak_count
779*38fd1498Szrj     {
780*38fd1498Szrj     public:
781*38fd1498Szrj       constexpr __weak_count() noexcept : _M_pi(nullptr)
782*38fd1498Szrj       { }
783*38fd1498Szrj 
784*38fd1498Szrj       __weak_count(const __shared_count<_Lp>& __r) noexcept
785*38fd1498Szrj       : _M_pi(__r._M_pi)
786*38fd1498Szrj       {
787*38fd1498Szrj 	if (_M_pi != nullptr)
788*38fd1498Szrj 	  _M_pi->_M_weak_add_ref();
789*38fd1498Szrj       }
790*38fd1498Szrj 
791*38fd1498Szrj       __weak_count(const __weak_count& __r) noexcept
792*38fd1498Szrj       : _M_pi(__r._M_pi)
793*38fd1498Szrj       {
794*38fd1498Szrj 	if (_M_pi != nullptr)
795*38fd1498Szrj 	  _M_pi->_M_weak_add_ref();
796*38fd1498Szrj       }
797*38fd1498Szrj 
798*38fd1498Szrj       __weak_count(__weak_count&& __r) noexcept
799*38fd1498Szrj       : _M_pi(__r._M_pi)
800*38fd1498Szrj       { __r._M_pi = nullptr; }
801*38fd1498Szrj 
802*38fd1498Szrj       ~__weak_count() noexcept
803*38fd1498Szrj       {
804*38fd1498Szrj 	if (_M_pi != nullptr)
805*38fd1498Szrj 	  _M_pi->_M_weak_release();
806*38fd1498Szrj       }
807*38fd1498Szrj 
808*38fd1498Szrj       __weak_count&
809*38fd1498Szrj       operator=(const __shared_count<_Lp>& __r) noexcept
810*38fd1498Szrj       {
811*38fd1498Szrj 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
812*38fd1498Szrj 	if (__tmp != nullptr)
813*38fd1498Szrj 	  __tmp->_M_weak_add_ref();
814*38fd1498Szrj 	if (_M_pi != nullptr)
815*38fd1498Szrj 	  _M_pi->_M_weak_release();
816*38fd1498Szrj 	_M_pi = __tmp;
817*38fd1498Szrj 	return *this;
818*38fd1498Szrj       }
819*38fd1498Szrj 
820*38fd1498Szrj       __weak_count&
821*38fd1498Szrj       operator=(const __weak_count& __r) noexcept
822*38fd1498Szrj       {
823*38fd1498Szrj 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
824*38fd1498Szrj 	if (__tmp != nullptr)
825*38fd1498Szrj 	  __tmp->_M_weak_add_ref();
826*38fd1498Szrj 	if (_M_pi != nullptr)
827*38fd1498Szrj 	  _M_pi->_M_weak_release();
828*38fd1498Szrj 	_M_pi = __tmp;
829*38fd1498Szrj 	return *this;
830*38fd1498Szrj       }
831*38fd1498Szrj 
832*38fd1498Szrj       __weak_count&
833*38fd1498Szrj       operator=(__weak_count&& __r) noexcept
834*38fd1498Szrj       {
835*38fd1498Szrj 	if (_M_pi != nullptr)
836*38fd1498Szrj 	  _M_pi->_M_weak_release();
837*38fd1498Szrj 	_M_pi = __r._M_pi;
838*38fd1498Szrj         __r._M_pi = nullptr;
839*38fd1498Szrj 	return *this;
840*38fd1498Szrj       }
841*38fd1498Szrj 
842*38fd1498Szrj       void
843*38fd1498Szrj       _M_swap(__weak_count& __r) noexcept
844*38fd1498Szrj       {
845*38fd1498Szrj 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
846*38fd1498Szrj 	__r._M_pi = _M_pi;
847*38fd1498Szrj 	_M_pi = __tmp;
848*38fd1498Szrj       }
849*38fd1498Szrj 
850*38fd1498Szrj       long
851*38fd1498Szrj       _M_get_use_count() const noexcept
852*38fd1498Szrj       { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
853*38fd1498Szrj 
854*38fd1498Szrj       bool
855*38fd1498Szrj       _M_less(const __weak_count& __rhs) const noexcept
856*38fd1498Szrj       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
857*38fd1498Szrj 
858*38fd1498Szrj       bool
859*38fd1498Szrj       _M_less(const __shared_count<_Lp>& __rhs) const noexcept
860*38fd1498Szrj       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
861*38fd1498Szrj 
862*38fd1498Szrj       // Friend function injected into enclosing namespace and found by ADL
863*38fd1498Szrj       friend inline bool
864*38fd1498Szrj       operator==(const __weak_count& __a, const __weak_count& __b) noexcept
865*38fd1498Szrj       { return __a._M_pi == __b._M_pi; }
866*38fd1498Szrj 
867*38fd1498Szrj     private:
868*38fd1498Szrj       friend class __shared_count<_Lp>;
869*38fd1498Szrj 
870*38fd1498Szrj       _Sp_counted_base<_Lp>*  _M_pi;
871*38fd1498Szrj     };
872*38fd1498Szrj 
873*38fd1498Szrj   // Now that __weak_count is defined we can define this constructor:
874*38fd1498Szrj   template<_Lock_policy _Lp>
875*38fd1498Szrj     inline
876*38fd1498Szrj     __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
877*38fd1498Szrj     : _M_pi(__r._M_pi)
878*38fd1498Szrj     {
879*38fd1498Szrj       if (_M_pi != nullptr)
880*38fd1498Szrj 	_M_pi->_M_add_ref_lock();
881*38fd1498Szrj       else
882*38fd1498Szrj 	__throw_bad_weak_ptr();
883*38fd1498Szrj     }
884*38fd1498Szrj 
885*38fd1498Szrj   // Now that __weak_count is defined we can define this constructor:
886*38fd1498Szrj   template<_Lock_policy _Lp>
887*38fd1498Szrj     inline
888*38fd1498Szrj     __shared_count<_Lp>::
889*38fd1498Szrj     __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t)
890*38fd1498Szrj     : _M_pi(__r._M_pi)
891*38fd1498Szrj     {
892*38fd1498Szrj       if (_M_pi != nullptr)
893*38fd1498Szrj 	if (!_M_pi->_M_add_ref_lock_nothrow())
894*38fd1498Szrj 	  _M_pi = nullptr;
895*38fd1498Szrj     }
896*38fd1498Szrj 
897*38fd1498Szrj #define __cpp_lib_shared_ptr_arrays 201603
898*38fd1498Szrj 
899*38fd1498Szrj   // Helper traits for shared_ptr of array:
900*38fd1498Szrj 
901*38fd1498Szrj   // A pointer type Y* is said to be compatible with a pointer type T* when
902*38fd1498Szrj   // either Y* is convertible to T* or Y is U[N] and T is U cv [].
903*38fd1498Szrj   template<typename _Yp_ptr, typename _Tp_ptr>
904*38fd1498Szrj     struct __sp_compatible_with
905*38fd1498Szrj     : false_type
906*38fd1498Szrj     { };
907*38fd1498Szrj 
908*38fd1498Szrj   template<typename _Yp, typename _Tp>
909*38fd1498Szrj     struct __sp_compatible_with<_Yp*, _Tp*>
910*38fd1498Szrj     : is_convertible<_Yp*, _Tp*>::type
911*38fd1498Szrj     { };
912*38fd1498Szrj 
913*38fd1498Szrj   template<typename _Up, size_t _Nm>
914*38fd1498Szrj     struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]>
915*38fd1498Szrj     : true_type
916*38fd1498Szrj     { };
917*38fd1498Szrj 
918*38fd1498Szrj   template<typename _Up, size_t _Nm>
919*38fd1498Szrj     struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]>
920*38fd1498Szrj     : true_type
921*38fd1498Szrj     { };
922*38fd1498Szrj 
923*38fd1498Szrj   template<typename _Up, size_t _Nm>
924*38fd1498Szrj     struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]>
925*38fd1498Szrj     : true_type
926*38fd1498Szrj     { };
927*38fd1498Szrj 
928*38fd1498Szrj   template<typename _Up, size_t _Nm>
929*38fd1498Szrj     struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]>
930*38fd1498Szrj     : true_type
931*38fd1498Szrj     { };
932*38fd1498Szrj 
933*38fd1498Szrj   // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N].
934*38fd1498Szrj   template<typename _Up, size_t _Nm, typename _Yp, typename = void>
935*38fd1498Szrj     struct __sp_is_constructible_arrN
936*38fd1498Szrj     : false_type
937*38fd1498Szrj     { };
938*38fd1498Szrj 
939*38fd1498Szrj   template<typename _Up, size_t _Nm, typename _Yp>
940*38fd1498Szrj     struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
941*38fd1498Szrj     : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
942*38fd1498Szrj     { };
943*38fd1498Szrj 
944*38fd1498Szrj   // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[].
945*38fd1498Szrj   template<typename _Up, typename _Yp, typename = void>
946*38fd1498Szrj     struct __sp_is_constructible_arr
947*38fd1498Szrj     : false_type
948*38fd1498Szrj     { };
949*38fd1498Szrj 
950*38fd1498Szrj   template<typename _Up, typename _Yp>
951*38fd1498Szrj     struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
952*38fd1498Szrj     : is_convertible<_Yp(*)[], _Up(*)[]>::type
953*38fd1498Szrj     { };
954*38fd1498Szrj 
955*38fd1498Szrj   // Trait to check if shared_ptr<T> can be constructed from Y*.
956*38fd1498Szrj   template<typename _Tp, typename _Yp>
957*38fd1498Szrj     struct __sp_is_constructible;
958*38fd1498Szrj 
959*38fd1498Szrj   // When T is U[N], Y(*)[N] shall be convertible to T*;
960*38fd1498Szrj   template<typename _Up, size_t _Nm, typename _Yp>
961*38fd1498Szrj     struct __sp_is_constructible<_Up[_Nm], _Yp>
962*38fd1498Szrj     : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
963*38fd1498Szrj     { };
964*38fd1498Szrj 
965*38fd1498Szrj   // when T is U[], Y(*)[] shall be convertible to T*;
966*38fd1498Szrj   template<typename _Up, typename _Yp>
967*38fd1498Szrj     struct __sp_is_constructible<_Up[], _Yp>
968*38fd1498Szrj     : __sp_is_constructible_arr<_Up, _Yp>::type
969*38fd1498Szrj     { };
970*38fd1498Szrj 
971*38fd1498Szrj   // otherwise, Y* shall be convertible to T*.
972*38fd1498Szrj   template<typename _Tp, typename _Yp>
973*38fd1498Szrj     struct __sp_is_constructible
974*38fd1498Szrj     : is_convertible<_Yp*, _Tp*>::type
975*38fd1498Szrj     { };
976*38fd1498Szrj 
977*38fd1498Szrj 
978*38fd1498Szrj   // Define operator* and operator-> for shared_ptr<T>.
979*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp,
980*38fd1498Szrj 	   bool = is_array<_Tp>::value, bool = is_void<_Tp>::value>
981*38fd1498Szrj     class __shared_ptr_access
982*38fd1498Szrj     {
983*38fd1498Szrj     public:
984*38fd1498Szrj       using element_type = _Tp;
985*38fd1498Szrj 
986*38fd1498Szrj       element_type&
987*38fd1498Szrj       operator*() const noexcept
988*38fd1498Szrj       {
989*38fd1498Szrj 	__glibcxx_assert(_M_get() != nullptr);
990*38fd1498Szrj 	return *_M_get();
991*38fd1498Szrj       }
992*38fd1498Szrj 
993*38fd1498Szrj       element_type*
994*38fd1498Szrj       operator->() const noexcept
995*38fd1498Szrj       {
996*38fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
997*38fd1498Szrj 	return _M_get();
998*38fd1498Szrj       }
999*38fd1498Szrj 
1000*38fd1498Szrj     private:
1001*38fd1498Szrj       element_type*
1002*38fd1498Szrj       _M_get() const noexcept
1003*38fd1498Szrj       { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
1004*38fd1498Szrj     };
1005*38fd1498Szrj 
1006*38fd1498Szrj   // Define operator-> for shared_ptr<cv void>.
1007*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1008*38fd1498Szrj     class __shared_ptr_access<_Tp, _Lp, false, true>
1009*38fd1498Szrj     {
1010*38fd1498Szrj     public:
1011*38fd1498Szrj       using element_type = _Tp;
1012*38fd1498Szrj 
1013*38fd1498Szrj       element_type*
1014*38fd1498Szrj       operator->() const noexcept
1015*38fd1498Szrj       {
1016*38fd1498Szrj 	auto __ptr = static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get();
1017*38fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr);
1018*38fd1498Szrj 	return __ptr;
1019*38fd1498Szrj       }
1020*38fd1498Szrj     };
1021*38fd1498Szrj 
1022*38fd1498Szrj   // Define operator[] for shared_ptr<T[]> and shared_ptr<T[N]>.
1023*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1024*38fd1498Szrj     class __shared_ptr_access<_Tp, _Lp, true, false>
1025*38fd1498Szrj     {
1026*38fd1498Szrj     public:
1027*38fd1498Szrj       using element_type = typename remove_extent<_Tp>::type;
1028*38fd1498Szrj 
1029*38fd1498Szrj #if __cplusplus <= 201402L
1030*38fd1498Szrj       [[__deprecated__("shared_ptr<T[]>::operator* is absent from C++17")]]
1031*38fd1498Szrj       element_type&
1032*38fd1498Szrj       operator*() const noexcept
1033*38fd1498Szrj       {
1034*38fd1498Szrj 	__glibcxx_assert(_M_get() != nullptr);
1035*38fd1498Szrj 	return *_M_get();
1036*38fd1498Szrj       }
1037*38fd1498Szrj 
1038*38fd1498Szrj       [[__deprecated__("shared_ptr<T[]>::operator-> is absent from C++17")]]
1039*38fd1498Szrj       element_type*
1040*38fd1498Szrj       operator->() const noexcept
1041*38fd1498Szrj       {
1042*38fd1498Szrj 	_GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
1043*38fd1498Szrj 	return _M_get();
1044*38fd1498Szrj       }
1045*38fd1498Szrj #endif
1046*38fd1498Szrj 
1047*38fd1498Szrj       element_type&
1048*38fd1498Szrj       operator[](ptrdiff_t __i) const
1049*38fd1498Szrj       {
1050*38fd1498Szrj 	__glibcxx_assert(_M_get() != nullptr);
1051*38fd1498Szrj 	__glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value);
1052*38fd1498Szrj 	return _M_get()[__i];
1053*38fd1498Szrj       }
1054*38fd1498Szrj 
1055*38fd1498Szrj     private:
1056*38fd1498Szrj       element_type*
1057*38fd1498Szrj       _M_get() const noexcept
1058*38fd1498Szrj       { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
1059*38fd1498Szrj     };
1060*38fd1498Szrj 
1061*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1062*38fd1498Szrj     class __shared_ptr
1063*38fd1498Szrj     : public __shared_ptr_access<_Tp, _Lp>
1064*38fd1498Szrj     {
1065*38fd1498Szrj     public:
1066*38fd1498Szrj       using element_type = typename remove_extent<_Tp>::type;
1067*38fd1498Szrj 
1068*38fd1498Szrj     private:
1069*38fd1498Szrj       // Constraint for taking ownership of a pointer of type _Yp*:
1070*38fd1498Szrj       template<typename _Yp>
1071*38fd1498Szrj 	using _SafeConv
1072*38fd1498Szrj 	  = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type;
1073*38fd1498Szrj 
1074*38fd1498Szrj       // Constraint for construction from shared_ptr and weak_ptr:
1075*38fd1498Szrj       template<typename _Yp, typename _Res = void>
1076*38fd1498Szrj 	using _Compatible = typename
1077*38fd1498Szrj 	  enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
1078*38fd1498Szrj 
1079*38fd1498Szrj       // Constraint for assignment from shared_ptr and weak_ptr:
1080*38fd1498Szrj       template<typename _Yp>
1081*38fd1498Szrj 	using _Assignable = _Compatible<_Yp, __shared_ptr&>;
1082*38fd1498Szrj 
1083*38fd1498Szrj       // Constraint for construction from unique_ptr:
1084*38fd1498Szrj       template<typename _Yp, typename _Del, typename _Res = void,
1085*38fd1498Szrj 	       typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer>
1086*38fd1498Szrj 	using _UniqCompatible = typename enable_if<__and_<
1087*38fd1498Szrj 	  __sp_compatible_with<_Yp*, _Tp*>, is_convertible<_Ptr, element_type*>
1088*38fd1498Szrj 	  >::value, _Res>::type;
1089*38fd1498Szrj 
1090*38fd1498Szrj       // Constraint for assignment from unique_ptr:
1091*38fd1498Szrj       template<typename _Yp, typename _Del>
1092*38fd1498Szrj 	using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>;
1093*38fd1498Szrj 
1094*38fd1498Szrj     public:
1095*38fd1498Szrj 
1096*38fd1498Szrj #if __cplusplus > 201402L
1097*38fd1498Szrj       using weak_type = __weak_ptr<_Tp, _Lp>;
1098*38fd1498Szrj #endif
1099*38fd1498Szrj 
1100*38fd1498Szrj       constexpr __shared_ptr() noexcept
1101*38fd1498Szrj       : _M_ptr(0), _M_refcount()
1102*38fd1498Szrj       { }
1103*38fd1498Szrj 
1104*38fd1498Szrj       template<typename _Yp, typename = _SafeConv<_Yp>>
1105*38fd1498Szrj 	explicit
1106*38fd1498Szrj 	__shared_ptr(_Yp* __p)
1107*38fd1498Szrj 	: _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type())
1108*38fd1498Szrj 	{
1109*38fd1498Szrj 	  static_assert( !is_void<_Yp>::value, "incomplete type" );
1110*38fd1498Szrj 	  static_assert( sizeof(_Yp) > 0, "incomplete type" );
1111*38fd1498Szrj 	  _M_enable_shared_from_this_with(__p);
1112*38fd1498Szrj 	}
1113*38fd1498Szrj 
1114*38fd1498Szrj       template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>>
1115*38fd1498Szrj 	__shared_ptr(_Yp* __p, _Deleter __d)
1116*38fd1498Szrj 	: _M_ptr(__p), _M_refcount(__p, std::move(__d))
1117*38fd1498Szrj 	{
1118*38fd1498Szrj 	  static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1119*38fd1498Szrj 	      "deleter expression d(p) is well-formed");
1120*38fd1498Szrj 	  _M_enable_shared_from_this_with(__p);
1121*38fd1498Szrj 	}
1122*38fd1498Szrj 
1123*38fd1498Szrj       template<typename _Yp, typename _Deleter, typename _Alloc,
1124*38fd1498Szrj 	       typename = _SafeConv<_Yp>>
1125*38fd1498Szrj 	__shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
1126*38fd1498Szrj 	: _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a))
1127*38fd1498Szrj 	{
1128*38fd1498Szrj 	  static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1129*38fd1498Szrj 	      "deleter expression d(p) is well-formed");
1130*38fd1498Szrj 	  _M_enable_shared_from_this_with(__p);
1131*38fd1498Szrj 	}
1132*38fd1498Szrj 
1133*38fd1498Szrj       template<typename _Deleter>
1134*38fd1498Szrj 	__shared_ptr(nullptr_t __p, _Deleter __d)
1135*38fd1498Szrj 	: _M_ptr(0), _M_refcount(__p, std::move(__d))
1136*38fd1498Szrj 	{ }
1137*38fd1498Szrj 
1138*38fd1498Szrj       template<typename _Deleter, typename _Alloc>
1139*38fd1498Szrj         __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
1140*38fd1498Szrj 	: _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a))
1141*38fd1498Szrj 	{ }
1142*38fd1498Szrj 
1143*38fd1498Szrj       template<typename _Yp>
1144*38fd1498Szrj 	__shared_ptr(const __shared_ptr<_Yp, _Lp>& __r,
1145*38fd1498Szrj 		     element_type* __p) noexcept
1146*38fd1498Szrj 	: _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
1147*38fd1498Szrj 	{ }
1148*38fd1498Szrj 
1149*38fd1498Szrj       __shared_ptr(const __shared_ptr&) noexcept = default;
1150*38fd1498Szrj       __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
1151*38fd1498Szrj       ~__shared_ptr() = default;
1152*38fd1498Szrj 
1153*38fd1498Szrj       template<typename _Yp, typename = _Compatible<_Yp>>
1154*38fd1498Szrj 	__shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1155*38fd1498Szrj 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1156*38fd1498Szrj 	{ }
1157*38fd1498Szrj 
1158*38fd1498Szrj       __shared_ptr(__shared_ptr&& __r) noexcept
1159*38fd1498Szrj       : _M_ptr(__r._M_ptr), _M_refcount()
1160*38fd1498Szrj       {
1161*38fd1498Szrj 	_M_refcount._M_swap(__r._M_refcount);
1162*38fd1498Szrj 	__r._M_ptr = 0;
1163*38fd1498Szrj       }
1164*38fd1498Szrj 
1165*38fd1498Szrj       template<typename _Yp, typename = _Compatible<_Yp>>
1166*38fd1498Szrj 	__shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1167*38fd1498Szrj 	: _M_ptr(__r._M_ptr), _M_refcount()
1168*38fd1498Szrj 	{
1169*38fd1498Szrj 	  _M_refcount._M_swap(__r._M_refcount);
1170*38fd1498Szrj 	  __r._M_ptr = 0;
1171*38fd1498Szrj 	}
1172*38fd1498Szrj 
1173*38fd1498Szrj       template<typename _Yp, typename = _Compatible<_Yp>>
1174*38fd1498Szrj 	explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r)
1175*38fd1498Szrj 	: _M_refcount(__r._M_refcount) // may throw
1176*38fd1498Szrj 	{
1177*38fd1498Szrj 	  // It is now safe to copy __r._M_ptr, as
1178*38fd1498Szrj 	  // _M_refcount(__r._M_refcount) did not throw.
1179*38fd1498Szrj 	  _M_ptr = __r._M_ptr;
1180*38fd1498Szrj 	}
1181*38fd1498Szrj 
1182*38fd1498Szrj       // If an exception is thrown this constructor has no effect.
1183*38fd1498Szrj       template<typename _Yp, typename _Del,
1184*38fd1498Szrj 	       typename = _UniqCompatible<_Yp, _Del>>
1185*38fd1498Szrj 	__shared_ptr(unique_ptr<_Yp, _Del>&& __r)
1186*38fd1498Szrj 	: _M_ptr(__r.get()), _M_refcount()
1187*38fd1498Szrj 	{
1188*38fd1498Szrj 	  auto __raw = __to_address(__r.get());
1189*38fd1498Szrj 	  _M_refcount = __shared_count<_Lp>(std::move(__r));
1190*38fd1498Szrj 	  _M_enable_shared_from_this_with(__raw);
1191*38fd1498Szrj 	}
1192*38fd1498Szrj 
1193*38fd1498Szrj #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
1194*38fd1498Szrj     protected:
1195*38fd1498Szrj       // If an exception is thrown this constructor has no effect.
1196*38fd1498Szrj       template<typename _Tp1, typename _Del,
1197*38fd1498Szrj 	       typename enable_if<__and_<
1198*38fd1498Szrj 		 __not_<is_array<_Tp>>, is_array<_Tp1>,
1199*38fd1498Szrj 	         is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*>
1200*38fd1498Szrj 	       >::value, bool>::type = true>
1201*38fd1498Szrj 	__shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete)
1202*38fd1498Szrj 	: _M_ptr(__r.get()), _M_refcount()
1203*38fd1498Szrj 	{
1204*38fd1498Szrj 	  auto __raw = __to_address(__r.get());
1205*38fd1498Szrj 	  _M_refcount = __shared_count<_Lp>(std::move(__r));
1206*38fd1498Szrj 	  _M_enable_shared_from_this_with(__raw);
1207*38fd1498Szrj 	}
1208*38fd1498Szrj     public:
1209*38fd1498Szrj #endif
1210*38fd1498Szrj 
1211*38fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
1212*38fd1498Szrj #pragma GCC diagnostic push
1213*38fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1214*38fd1498Szrj       // Postcondition: use_count() == 1 and __r.get() == 0
1215*38fd1498Szrj       template<typename _Yp, typename = _Compatible<_Yp>>
1216*38fd1498Szrj 	__shared_ptr(auto_ptr<_Yp>&& __r);
1217*38fd1498Szrj #pragma GCC diagnostic pop
1218*38fd1498Szrj #endif
1219*38fd1498Szrj 
1220*38fd1498Szrj       constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
1221*38fd1498Szrj 
1222*38fd1498Szrj       template<typename _Yp>
1223*38fd1498Szrj 	_Assignable<_Yp>
1224*38fd1498Szrj 	operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1225*38fd1498Szrj 	{
1226*38fd1498Szrj 	  _M_ptr = __r._M_ptr;
1227*38fd1498Szrj 	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
1228*38fd1498Szrj 	  return *this;
1229*38fd1498Szrj 	}
1230*38fd1498Szrj 
1231*38fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
1232*38fd1498Szrj #pragma GCC diagnostic push
1233*38fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1234*38fd1498Szrj       template<typename _Yp>
1235*38fd1498Szrj 	_Assignable<_Yp>
1236*38fd1498Szrj 	operator=(auto_ptr<_Yp>&& __r)
1237*38fd1498Szrj 	{
1238*38fd1498Szrj 	  __shared_ptr(std::move(__r)).swap(*this);
1239*38fd1498Szrj 	  return *this;
1240*38fd1498Szrj 	}
1241*38fd1498Szrj #pragma GCC diagnostic pop
1242*38fd1498Szrj #endif
1243*38fd1498Szrj 
1244*38fd1498Szrj       __shared_ptr&
1245*38fd1498Szrj       operator=(__shared_ptr&& __r) noexcept
1246*38fd1498Szrj       {
1247*38fd1498Szrj 	__shared_ptr(std::move(__r)).swap(*this);
1248*38fd1498Szrj 	return *this;
1249*38fd1498Szrj       }
1250*38fd1498Szrj 
1251*38fd1498Szrj       template<class _Yp>
1252*38fd1498Szrj 	_Assignable<_Yp>
1253*38fd1498Szrj 	operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1254*38fd1498Szrj 	{
1255*38fd1498Szrj 	  __shared_ptr(std::move(__r)).swap(*this);
1256*38fd1498Szrj 	  return *this;
1257*38fd1498Szrj 	}
1258*38fd1498Szrj 
1259*38fd1498Szrj       template<typename _Yp, typename _Del>
1260*38fd1498Szrj 	_UniqAssignable<_Yp, _Del>
1261*38fd1498Szrj 	operator=(unique_ptr<_Yp, _Del>&& __r)
1262*38fd1498Szrj 	{
1263*38fd1498Szrj 	  __shared_ptr(std::move(__r)).swap(*this);
1264*38fd1498Szrj 	  return *this;
1265*38fd1498Szrj 	}
1266*38fd1498Szrj 
1267*38fd1498Szrj       void
1268*38fd1498Szrj       reset() noexcept
1269*38fd1498Szrj       { __shared_ptr().swap(*this); }
1270*38fd1498Szrj 
1271*38fd1498Szrj       template<typename _Yp>
1272*38fd1498Szrj 	_SafeConv<_Yp>
1273*38fd1498Szrj 	reset(_Yp* __p) // _Yp must be complete.
1274*38fd1498Szrj 	{
1275*38fd1498Szrj 	  // Catch self-reset errors.
1276*38fd1498Szrj 	  __glibcxx_assert(__p == 0 || __p != _M_ptr);
1277*38fd1498Szrj 	  __shared_ptr(__p).swap(*this);
1278*38fd1498Szrj 	}
1279*38fd1498Szrj 
1280*38fd1498Szrj       template<typename _Yp, typename _Deleter>
1281*38fd1498Szrj 	_SafeConv<_Yp>
1282*38fd1498Szrj 	reset(_Yp* __p, _Deleter __d)
1283*38fd1498Szrj 	{ __shared_ptr(__p, std::move(__d)).swap(*this); }
1284*38fd1498Szrj 
1285*38fd1498Szrj       template<typename _Yp, typename _Deleter, typename _Alloc>
1286*38fd1498Szrj 	_SafeConv<_Yp>
1287*38fd1498Szrj 	reset(_Yp* __p, _Deleter __d, _Alloc __a)
1288*38fd1498Szrj         { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); }
1289*38fd1498Szrj 
1290*38fd1498Szrj       element_type*
1291*38fd1498Szrj       get() const noexcept
1292*38fd1498Szrj       { return _M_ptr; }
1293*38fd1498Szrj 
1294*38fd1498Szrj       explicit operator bool() const // never throws
1295*38fd1498Szrj       { return _M_ptr == 0 ? false : true; }
1296*38fd1498Szrj 
1297*38fd1498Szrj       bool
1298*38fd1498Szrj       unique() const noexcept
1299*38fd1498Szrj       { return _M_refcount._M_unique(); }
1300*38fd1498Szrj 
1301*38fd1498Szrj       long
1302*38fd1498Szrj       use_count() const noexcept
1303*38fd1498Szrj       { return _M_refcount._M_get_use_count(); }
1304*38fd1498Szrj 
1305*38fd1498Szrj       void
1306*38fd1498Szrj       swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
1307*38fd1498Szrj       {
1308*38fd1498Szrj 	std::swap(_M_ptr, __other._M_ptr);
1309*38fd1498Szrj 	_M_refcount._M_swap(__other._M_refcount);
1310*38fd1498Szrj       }
1311*38fd1498Szrj 
1312*38fd1498Szrj       template<typename _Tp1>
1313*38fd1498Szrj 	bool
1314*38fd1498Szrj 	owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1315*38fd1498Szrj 	{ return _M_refcount._M_less(__rhs._M_refcount); }
1316*38fd1498Szrj 
1317*38fd1498Szrj       template<typename _Tp1>
1318*38fd1498Szrj 	bool
1319*38fd1498Szrj 	owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1320*38fd1498Szrj 	{ return _M_refcount._M_less(__rhs._M_refcount); }
1321*38fd1498Szrj 
1322*38fd1498Szrj     protected:
1323*38fd1498Szrj       // This constructor is non-standard, it is used by allocate_shared.
1324*38fd1498Szrj       template<typename _Alloc, typename... _Args>
1325*38fd1498Szrj 	__shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
1326*38fd1498Szrj 		     _Args&&... __args)
1327*38fd1498Szrj 	: _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
1328*38fd1498Szrj 				std::forward<_Args>(__args)...)
1329*38fd1498Szrj 	{
1330*38fd1498Szrj 	  // _M_ptr needs to point to the newly constructed object.
1331*38fd1498Szrj 	  // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
1332*38fd1498Szrj #if __cpp_rtti
1333*38fd1498Szrj 	  void* __p = _M_refcount._M_get_deleter(typeid(__tag));
1334*38fd1498Szrj #else
1335*38fd1498Szrj 	  void* __p = _M_refcount._M_get_deleter(_Sp_make_shared_tag::_S_ti());
1336*38fd1498Szrj #endif
1337*38fd1498Szrj 	  _M_ptr = static_cast<_Tp*>(__p);
1338*38fd1498Szrj 	  _M_enable_shared_from_this_with(_M_ptr);
1339*38fd1498Szrj 	}
1340*38fd1498Szrj 
1341*38fd1498Szrj       template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
1342*38fd1498Szrj 	       typename... _Args>
1343*38fd1498Szrj 	friend __shared_ptr<_Tp1, _Lp1>
1344*38fd1498Szrj 	__allocate_shared(const _Alloc& __a, _Args&&... __args);
1345*38fd1498Szrj 
1346*38fd1498Szrj       // This constructor is used by __weak_ptr::lock() and
1347*38fd1498Szrj       // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
1348*38fd1498Szrj       __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t)
1349*38fd1498Szrj       : _M_refcount(__r._M_refcount, std::nothrow)
1350*38fd1498Szrj       {
1351*38fd1498Szrj 	_M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr;
1352*38fd1498Szrj       }
1353*38fd1498Szrj 
1354*38fd1498Szrj       friend class __weak_ptr<_Tp, _Lp>;
1355*38fd1498Szrj 
1356*38fd1498Szrj     private:
1357*38fd1498Szrj 
1358*38fd1498Szrj       template<typename _Yp>
1359*38fd1498Szrj 	using __esft_base_t = decltype(__enable_shared_from_this_base(
1360*38fd1498Szrj 	      std::declval<const __shared_count<_Lp>&>(),
1361*38fd1498Szrj 	      std::declval<_Yp*>()));
1362*38fd1498Szrj 
1363*38fd1498Szrj       // Detect an accessible and unambiguous enable_shared_from_this base.
1364*38fd1498Szrj       template<typename _Yp, typename = void>
1365*38fd1498Szrj 	struct __has_esft_base
1366*38fd1498Szrj 	: false_type { };
1367*38fd1498Szrj 
1368*38fd1498Szrj       template<typename _Yp>
1369*38fd1498Szrj 	struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
1370*38fd1498Szrj 	: __not_<is_array<_Tp>> { }; // No enable shared_from_this for arrays
1371*38fd1498Szrj 
1372*38fd1498Szrj       template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1373*38fd1498Szrj 	typename enable_if<__has_esft_base<_Yp2>::value>::type
1374*38fd1498Szrj 	_M_enable_shared_from_this_with(_Yp* __p) noexcept
1375*38fd1498Szrj 	{
1376*38fd1498Szrj 	  if (auto __base = __enable_shared_from_this_base(_M_refcount, __p))
1377*38fd1498Szrj 	    __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount);
1378*38fd1498Szrj 	}
1379*38fd1498Szrj 
1380*38fd1498Szrj       template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1381*38fd1498Szrj 	typename enable_if<!__has_esft_base<_Yp2>::value>::type
1382*38fd1498Szrj 	_M_enable_shared_from_this_with(_Yp*) noexcept
1383*38fd1498Szrj 	{ }
1384*38fd1498Szrj 
1385*38fd1498Szrj       void*
1386*38fd1498Szrj       _M_get_deleter(const std::type_info& __ti) const noexcept
1387*38fd1498Szrj       { return _M_refcount._M_get_deleter(__ti); }
1388*38fd1498Szrj 
1389*38fd1498Szrj       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1390*38fd1498Szrj       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1391*38fd1498Szrj 
1392*38fd1498Szrj       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
1393*38fd1498Szrj 	friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
1394*38fd1498Szrj 
1395*38fd1498Szrj       template<typename _Del, typename _Tp1>
1396*38fd1498Szrj 	friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept;
1397*38fd1498Szrj 
1398*38fd1498Szrj       element_type*	   _M_ptr;         // Contained pointer.
1399*38fd1498Szrj       __shared_count<_Lp>  _M_refcount;    // Reference counter.
1400*38fd1498Szrj     };
1401*38fd1498Szrj 
1402*38fd1498Szrj 
1403*38fd1498Szrj   // 20.7.2.2.7 shared_ptr comparisons
1404*38fd1498Szrj   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1405*38fd1498Szrj     inline bool
1406*38fd1498Szrj     operator==(const __shared_ptr<_Tp1, _Lp>& __a,
1407*38fd1498Szrj 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1408*38fd1498Szrj     { return __a.get() == __b.get(); }
1409*38fd1498Szrj 
1410*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1411*38fd1498Szrj     inline bool
1412*38fd1498Szrj     operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1413*38fd1498Szrj     { return !__a; }
1414*38fd1498Szrj 
1415*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1416*38fd1498Szrj     inline bool
1417*38fd1498Szrj     operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1418*38fd1498Szrj     { return !__a; }
1419*38fd1498Szrj 
1420*38fd1498Szrj   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1421*38fd1498Szrj     inline bool
1422*38fd1498Szrj     operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
1423*38fd1498Szrj 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1424*38fd1498Szrj     { return __a.get() != __b.get(); }
1425*38fd1498Szrj 
1426*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1427*38fd1498Szrj     inline bool
1428*38fd1498Szrj     operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1429*38fd1498Szrj     { return (bool)__a; }
1430*38fd1498Szrj 
1431*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1432*38fd1498Szrj     inline bool
1433*38fd1498Szrj     operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1434*38fd1498Szrj     { return (bool)__a; }
1435*38fd1498Szrj 
1436*38fd1498Szrj   template<typename _Tp, typename _Up, _Lock_policy _Lp>
1437*38fd1498Szrj     inline bool
1438*38fd1498Szrj     operator<(const __shared_ptr<_Tp, _Lp>& __a,
1439*38fd1498Szrj 	      const __shared_ptr<_Up, _Lp>& __b) noexcept
1440*38fd1498Szrj     {
1441*38fd1498Szrj       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1442*38fd1498Szrj       using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type;
1443*38fd1498Szrj       using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
1444*38fd1498Szrj       return less<_Vp>()(__a.get(), __b.get());
1445*38fd1498Szrj     }
1446*38fd1498Szrj 
1447*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1448*38fd1498Szrj     inline bool
1449*38fd1498Szrj     operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1450*38fd1498Szrj     {
1451*38fd1498Szrj       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1452*38fd1498Szrj       return less<_Tp_elt*>()(__a.get(), nullptr);
1453*38fd1498Szrj     }
1454*38fd1498Szrj 
1455*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1456*38fd1498Szrj     inline bool
1457*38fd1498Szrj     operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1458*38fd1498Szrj     {
1459*38fd1498Szrj       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1460*38fd1498Szrj       return less<_Tp_elt*>()(nullptr, __a.get());
1461*38fd1498Szrj     }
1462*38fd1498Szrj 
1463*38fd1498Szrj   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1464*38fd1498Szrj     inline bool
1465*38fd1498Szrj     operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
1466*38fd1498Szrj 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1467*38fd1498Szrj     { return !(__b < __a); }
1468*38fd1498Szrj 
1469*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1470*38fd1498Szrj     inline bool
1471*38fd1498Szrj     operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1472*38fd1498Szrj     { return !(nullptr < __a); }
1473*38fd1498Szrj 
1474*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1475*38fd1498Szrj     inline bool
1476*38fd1498Szrj     operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1477*38fd1498Szrj     { return !(__a < nullptr); }
1478*38fd1498Szrj 
1479*38fd1498Szrj   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1480*38fd1498Szrj     inline bool
1481*38fd1498Szrj     operator>(const __shared_ptr<_Tp1, _Lp>& __a,
1482*38fd1498Szrj 	      const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1483*38fd1498Szrj     { return (__b < __a); }
1484*38fd1498Szrj 
1485*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1486*38fd1498Szrj     inline bool
1487*38fd1498Szrj     operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1488*38fd1498Szrj     { return nullptr < __a; }
1489*38fd1498Szrj 
1490*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1491*38fd1498Szrj     inline bool
1492*38fd1498Szrj     operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1493*38fd1498Szrj     { return __a < nullptr; }
1494*38fd1498Szrj 
1495*38fd1498Szrj   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1496*38fd1498Szrj     inline bool
1497*38fd1498Szrj     operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
1498*38fd1498Szrj 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1499*38fd1498Szrj     { return !(__a < __b); }
1500*38fd1498Szrj 
1501*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1502*38fd1498Szrj     inline bool
1503*38fd1498Szrj     operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1504*38fd1498Szrj     { return !(__a < nullptr); }
1505*38fd1498Szrj 
1506*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1507*38fd1498Szrj     inline bool
1508*38fd1498Szrj     operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1509*38fd1498Szrj     { return !(nullptr < __a); }
1510*38fd1498Szrj 
1511*38fd1498Szrj   template<typename _Sp>
1512*38fd1498Szrj     struct _Sp_less : public binary_function<_Sp, _Sp, bool>
1513*38fd1498Szrj     {
1514*38fd1498Szrj       bool
1515*38fd1498Szrj       operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept
1516*38fd1498Szrj       {
1517*38fd1498Szrj 	typedef typename _Sp::element_type element_type;
1518*38fd1498Szrj 	return std::less<element_type*>()(__lhs.get(), __rhs.get());
1519*38fd1498Szrj       }
1520*38fd1498Szrj     };
1521*38fd1498Szrj 
1522*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1523*38fd1498Szrj     struct less<__shared_ptr<_Tp, _Lp>>
1524*38fd1498Szrj     : public _Sp_less<__shared_ptr<_Tp, _Lp>>
1525*38fd1498Szrj     { };
1526*38fd1498Szrj 
1527*38fd1498Szrj   // 20.7.2.2.8 shared_ptr specialized algorithms.
1528*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1529*38fd1498Szrj     inline void
1530*38fd1498Szrj     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
1531*38fd1498Szrj     { __a.swap(__b); }
1532*38fd1498Szrj 
1533*38fd1498Szrj   // 20.7.2.2.9 shared_ptr casts
1534*38fd1498Szrj 
1535*38fd1498Szrj   // The seemingly equivalent code:
1536*38fd1498Szrj   // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
1537*38fd1498Szrj   // will eventually result in undefined behaviour, attempting to
1538*38fd1498Szrj   // delete the same object twice.
1539*38fd1498Szrj   /// static_pointer_cast
1540*38fd1498Szrj   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1541*38fd1498Szrj     inline __shared_ptr<_Tp, _Lp>
1542*38fd1498Szrj     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1543*38fd1498Szrj     {
1544*38fd1498Szrj       using _Sp = __shared_ptr<_Tp, _Lp>;
1545*38fd1498Szrj       return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
1546*38fd1498Szrj     }
1547*38fd1498Szrj 
1548*38fd1498Szrj   // The seemingly equivalent code:
1549*38fd1498Szrj   // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
1550*38fd1498Szrj   // will eventually result in undefined behaviour, attempting to
1551*38fd1498Szrj   // delete the same object twice.
1552*38fd1498Szrj   /// const_pointer_cast
1553*38fd1498Szrj   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1554*38fd1498Szrj     inline __shared_ptr<_Tp, _Lp>
1555*38fd1498Szrj     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1556*38fd1498Szrj     {
1557*38fd1498Szrj       using _Sp = __shared_ptr<_Tp, _Lp>;
1558*38fd1498Szrj       return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
1559*38fd1498Szrj     }
1560*38fd1498Szrj 
1561*38fd1498Szrj   // The seemingly equivalent code:
1562*38fd1498Szrj   // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
1563*38fd1498Szrj   // will eventually result in undefined behaviour, attempting to
1564*38fd1498Szrj   // delete the same object twice.
1565*38fd1498Szrj   /// dynamic_pointer_cast
1566*38fd1498Szrj   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1567*38fd1498Szrj     inline __shared_ptr<_Tp, _Lp>
1568*38fd1498Szrj     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1569*38fd1498Szrj     {
1570*38fd1498Szrj       using _Sp = __shared_ptr<_Tp, _Lp>;
1571*38fd1498Szrj       if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
1572*38fd1498Szrj 	return _Sp(__r, __p);
1573*38fd1498Szrj       return _Sp();
1574*38fd1498Szrj     }
1575*38fd1498Szrj 
1576*38fd1498Szrj #if __cplusplus > 201402L
1577*38fd1498Szrj   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1578*38fd1498Szrj     inline __shared_ptr<_Tp, _Lp>
1579*38fd1498Szrj     reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1580*38fd1498Szrj     {
1581*38fd1498Szrj       using _Sp = __shared_ptr<_Tp, _Lp>;
1582*38fd1498Szrj       return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
1583*38fd1498Szrj     }
1584*38fd1498Szrj #endif
1585*38fd1498Szrj 
1586*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1587*38fd1498Szrj     class __weak_ptr
1588*38fd1498Szrj     {
1589*38fd1498Szrj       template<typename _Yp, typename _Res = void>
1590*38fd1498Szrj 	using _Compatible = typename
1591*38fd1498Szrj 	  enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
1592*38fd1498Szrj 
1593*38fd1498Szrj       // Constraint for assignment from shared_ptr and weak_ptr:
1594*38fd1498Szrj       template<typename _Yp>
1595*38fd1498Szrj 	using _Assignable = _Compatible<_Yp, __weak_ptr&>;
1596*38fd1498Szrj 
1597*38fd1498Szrj     public:
1598*38fd1498Szrj       using element_type = typename remove_extent<_Tp>::type;
1599*38fd1498Szrj 
1600*38fd1498Szrj       constexpr __weak_ptr() noexcept
1601*38fd1498Szrj       : _M_ptr(nullptr), _M_refcount()
1602*38fd1498Szrj       { }
1603*38fd1498Szrj 
1604*38fd1498Szrj       __weak_ptr(const __weak_ptr&) noexcept = default;
1605*38fd1498Szrj 
1606*38fd1498Szrj       ~__weak_ptr() = default;
1607*38fd1498Szrj 
1608*38fd1498Szrj       // The "obvious" converting constructor implementation:
1609*38fd1498Szrj       //
1610*38fd1498Szrj       //  template<typename _Tp1>
1611*38fd1498Szrj       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
1612*38fd1498Szrj       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
1613*38fd1498Szrj       //    { }
1614*38fd1498Szrj       //
1615*38fd1498Szrj       // has a serious problem.
1616*38fd1498Szrj       //
1617*38fd1498Szrj       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
1618*38fd1498Szrj       //  conversion may require access to *__r._M_ptr (virtual inheritance).
1619*38fd1498Szrj       //
1620*38fd1498Szrj       // It is not possible to avoid spurious access violations since
1621*38fd1498Szrj       // in multithreaded programs __r._M_ptr may be invalidated at any point.
1622*38fd1498Szrj       template<typename _Yp, typename = _Compatible<_Yp>>
1623*38fd1498Szrj 	__weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept
1624*38fd1498Szrj 	: _M_refcount(__r._M_refcount)
1625*38fd1498Szrj         { _M_ptr = __r.lock().get(); }
1626*38fd1498Szrj 
1627*38fd1498Szrj       template<typename _Yp, typename = _Compatible<_Yp>>
1628*38fd1498Szrj 	__weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1629*38fd1498Szrj 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1630*38fd1498Szrj 	{ }
1631*38fd1498Szrj 
1632*38fd1498Szrj       __weak_ptr(__weak_ptr&& __r) noexcept
1633*38fd1498Szrj       : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
1634*38fd1498Szrj       { __r._M_ptr = nullptr; }
1635*38fd1498Szrj 
1636*38fd1498Szrj       template<typename _Yp, typename = _Compatible<_Yp>>
1637*38fd1498Szrj 	__weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept
1638*38fd1498Szrj 	: _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount))
1639*38fd1498Szrj         { __r._M_ptr = nullptr; }
1640*38fd1498Szrj 
1641*38fd1498Szrj       __weak_ptr&
1642*38fd1498Szrj       operator=(const __weak_ptr& __r) noexcept = default;
1643*38fd1498Szrj 
1644*38fd1498Szrj       template<typename _Yp>
1645*38fd1498Szrj 	_Assignable<_Yp>
1646*38fd1498Szrj 	operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept
1647*38fd1498Szrj 	{
1648*38fd1498Szrj 	  _M_ptr = __r.lock().get();
1649*38fd1498Szrj 	  _M_refcount = __r._M_refcount;
1650*38fd1498Szrj 	  return *this;
1651*38fd1498Szrj 	}
1652*38fd1498Szrj 
1653*38fd1498Szrj       template<typename _Yp>
1654*38fd1498Szrj 	_Assignable<_Yp>
1655*38fd1498Szrj 	operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1656*38fd1498Szrj 	{
1657*38fd1498Szrj 	  _M_ptr = __r._M_ptr;
1658*38fd1498Szrj 	  _M_refcount = __r._M_refcount;
1659*38fd1498Szrj 	  return *this;
1660*38fd1498Szrj 	}
1661*38fd1498Szrj 
1662*38fd1498Szrj       __weak_ptr&
1663*38fd1498Szrj       operator=(__weak_ptr&& __r) noexcept
1664*38fd1498Szrj       {
1665*38fd1498Szrj 	_M_ptr = __r._M_ptr;
1666*38fd1498Szrj 	_M_refcount = std::move(__r._M_refcount);
1667*38fd1498Szrj 	__r._M_ptr = nullptr;
1668*38fd1498Szrj 	return *this;
1669*38fd1498Szrj       }
1670*38fd1498Szrj 
1671*38fd1498Szrj       template<typename _Yp>
1672*38fd1498Szrj 	_Assignable<_Yp>
1673*38fd1498Szrj 	operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept
1674*38fd1498Szrj 	{
1675*38fd1498Szrj 	  _M_ptr = __r.lock().get();
1676*38fd1498Szrj 	  _M_refcount = std::move(__r._M_refcount);
1677*38fd1498Szrj 	  __r._M_ptr = nullptr;
1678*38fd1498Szrj 	  return *this;
1679*38fd1498Szrj 	}
1680*38fd1498Szrj 
1681*38fd1498Szrj       __shared_ptr<_Tp, _Lp>
1682*38fd1498Szrj       lock() const noexcept
1683*38fd1498Szrj       { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); }
1684*38fd1498Szrj 
1685*38fd1498Szrj       long
1686*38fd1498Szrj       use_count() const noexcept
1687*38fd1498Szrj       { return _M_refcount._M_get_use_count(); }
1688*38fd1498Szrj 
1689*38fd1498Szrj       bool
1690*38fd1498Szrj       expired() const noexcept
1691*38fd1498Szrj       { return _M_refcount._M_get_use_count() == 0; }
1692*38fd1498Szrj 
1693*38fd1498Szrj       template<typename _Tp1>
1694*38fd1498Szrj 	bool
1695*38fd1498Szrj 	owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept
1696*38fd1498Szrj 	{ return _M_refcount._M_less(__rhs._M_refcount); }
1697*38fd1498Szrj 
1698*38fd1498Szrj       template<typename _Tp1>
1699*38fd1498Szrj 	bool
1700*38fd1498Szrj 	owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept
1701*38fd1498Szrj 	{ return _M_refcount._M_less(__rhs._M_refcount); }
1702*38fd1498Szrj 
1703*38fd1498Szrj       void
1704*38fd1498Szrj       reset() noexcept
1705*38fd1498Szrj       { __weak_ptr().swap(*this); }
1706*38fd1498Szrj 
1707*38fd1498Szrj       void
1708*38fd1498Szrj       swap(__weak_ptr& __s) noexcept
1709*38fd1498Szrj       {
1710*38fd1498Szrj 	std::swap(_M_ptr, __s._M_ptr);
1711*38fd1498Szrj 	_M_refcount._M_swap(__s._M_refcount);
1712*38fd1498Szrj       }
1713*38fd1498Szrj 
1714*38fd1498Szrj     private:
1715*38fd1498Szrj       // Used by __enable_shared_from_this.
1716*38fd1498Szrj       void
1717*38fd1498Szrj       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
1718*38fd1498Szrj       {
1719*38fd1498Szrj 	if (use_count() == 0)
1720*38fd1498Szrj 	  {
1721*38fd1498Szrj 	    _M_ptr = __ptr;
1722*38fd1498Szrj 	    _M_refcount = __refcount;
1723*38fd1498Szrj 	  }
1724*38fd1498Szrj       }
1725*38fd1498Szrj 
1726*38fd1498Szrj       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1727*38fd1498Szrj       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1728*38fd1498Szrj       friend class __enable_shared_from_this<_Tp, _Lp>;
1729*38fd1498Szrj       friend class enable_shared_from_this<_Tp>;
1730*38fd1498Szrj 
1731*38fd1498Szrj       element_type*	 _M_ptr;         // Contained pointer.
1732*38fd1498Szrj       __weak_count<_Lp>  _M_refcount;    // Reference counter.
1733*38fd1498Szrj     };
1734*38fd1498Szrj 
1735*38fd1498Szrj   // 20.7.2.3.6 weak_ptr specialized algorithms.
1736*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1737*38fd1498Szrj     inline void
1738*38fd1498Szrj     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
1739*38fd1498Szrj     { __a.swap(__b); }
1740*38fd1498Szrj 
1741*38fd1498Szrj   template<typename _Tp, typename _Tp1>
1742*38fd1498Szrj     struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
1743*38fd1498Szrj     {
1744*38fd1498Szrj       bool
1745*38fd1498Szrj       operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept
1746*38fd1498Szrj       { return __lhs.owner_before(__rhs); }
1747*38fd1498Szrj 
1748*38fd1498Szrj       bool
1749*38fd1498Szrj       operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept
1750*38fd1498Szrj       { return __lhs.owner_before(__rhs); }
1751*38fd1498Szrj 
1752*38fd1498Szrj       bool
1753*38fd1498Szrj       operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept
1754*38fd1498Szrj       { return __lhs.owner_before(__rhs); }
1755*38fd1498Szrj     };
1756*38fd1498Szrj 
1757*38fd1498Szrj   template<>
1758*38fd1498Szrj     struct _Sp_owner_less<void, void>
1759*38fd1498Szrj     {
1760*38fd1498Szrj       template<typename _Tp, typename _Up>
1761*38fd1498Szrj 	auto
1762*38fd1498Szrj 	operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept
1763*38fd1498Szrj 	-> decltype(__lhs.owner_before(__rhs))
1764*38fd1498Szrj 	{ return __lhs.owner_before(__rhs); }
1765*38fd1498Szrj 
1766*38fd1498Szrj       using is_transparent = void;
1767*38fd1498Szrj     };
1768*38fd1498Szrj 
1769*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1770*38fd1498Szrj     struct owner_less<__shared_ptr<_Tp, _Lp>>
1771*38fd1498Szrj     : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
1772*38fd1498Szrj     { };
1773*38fd1498Szrj 
1774*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1775*38fd1498Szrj     struct owner_less<__weak_ptr<_Tp, _Lp>>
1776*38fd1498Szrj     : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
1777*38fd1498Szrj     { };
1778*38fd1498Szrj 
1779*38fd1498Szrj 
1780*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1781*38fd1498Szrj     class __enable_shared_from_this
1782*38fd1498Szrj     {
1783*38fd1498Szrj     protected:
1784*38fd1498Szrj       constexpr __enable_shared_from_this() noexcept { }
1785*38fd1498Szrj 
1786*38fd1498Szrj       __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
1787*38fd1498Szrj 
1788*38fd1498Szrj       __enable_shared_from_this&
1789*38fd1498Szrj       operator=(const __enable_shared_from_this&) noexcept
1790*38fd1498Szrj       { return *this; }
1791*38fd1498Szrj 
1792*38fd1498Szrj       ~__enable_shared_from_this() { }
1793*38fd1498Szrj 
1794*38fd1498Szrj     public:
1795*38fd1498Szrj       __shared_ptr<_Tp, _Lp>
1796*38fd1498Szrj       shared_from_this()
1797*38fd1498Szrj       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
1798*38fd1498Szrj 
1799*38fd1498Szrj       __shared_ptr<const _Tp, _Lp>
1800*38fd1498Szrj       shared_from_this() const
1801*38fd1498Szrj       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
1802*38fd1498Szrj 
1803*38fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1804*38fd1498Szrj       __weak_ptr<_Tp, _Lp>
1805*38fd1498Szrj       weak_from_this() noexcept
1806*38fd1498Szrj       { return this->_M_weak_this; }
1807*38fd1498Szrj 
1808*38fd1498Szrj       __weak_ptr<const _Tp, _Lp>
1809*38fd1498Szrj       weak_from_this() const noexcept
1810*38fd1498Szrj       { return this->_M_weak_this; }
1811*38fd1498Szrj #endif
1812*38fd1498Szrj 
1813*38fd1498Szrj     private:
1814*38fd1498Szrj       template<typename _Tp1>
1815*38fd1498Szrj 	void
1816*38fd1498Szrj 	_M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
1817*38fd1498Szrj 	{ _M_weak_this._M_assign(__p, __n); }
1818*38fd1498Szrj 
1819*38fd1498Szrj       friend const __enable_shared_from_this*
1820*38fd1498Szrj       __enable_shared_from_this_base(const __shared_count<_Lp>&,
1821*38fd1498Szrj 				     const __enable_shared_from_this* __p)
1822*38fd1498Szrj       { return __p; }
1823*38fd1498Szrj 
1824*38fd1498Szrj       template<typename, _Lock_policy>
1825*38fd1498Szrj 	friend class __shared_ptr;
1826*38fd1498Szrj 
1827*38fd1498Szrj       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
1828*38fd1498Szrj     };
1829*38fd1498Szrj 
1830*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
1831*38fd1498Szrj     inline __shared_ptr<_Tp, _Lp>
1832*38fd1498Szrj     __allocate_shared(const _Alloc& __a, _Args&&... __args)
1833*38fd1498Szrj     {
1834*38fd1498Szrj       return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a,
1835*38fd1498Szrj 				    std::forward<_Args>(__args)...);
1836*38fd1498Szrj     }
1837*38fd1498Szrj 
1838*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp, typename... _Args>
1839*38fd1498Szrj     inline __shared_ptr<_Tp, _Lp>
1840*38fd1498Szrj     __make_shared(_Args&&... __args)
1841*38fd1498Szrj     {
1842*38fd1498Szrj       typedef typename std::remove_const<_Tp>::type _Tp_nc;
1843*38fd1498Szrj       return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
1844*38fd1498Szrj 					      std::forward<_Args>(__args)...);
1845*38fd1498Szrj     }
1846*38fd1498Szrj 
1847*38fd1498Szrj   /// std::hash specialization for __shared_ptr.
1848*38fd1498Szrj   template<typename _Tp, _Lock_policy _Lp>
1849*38fd1498Szrj     struct hash<__shared_ptr<_Tp, _Lp>>
1850*38fd1498Szrj     : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
1851*38fd1498Szrj     {
1852*38fd1498Szrj       size_t
1853*38fd1498Szrj       operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
1854*38fd1498Szrj       {
1855*38fd1498Szrj 	return hash<typename __shared_ptr<_Tp, _Lp>::element_type*>()(
1856*38fd1498Szrj 	    __s.get());
1857*38fd1498Szrj       }
1858*38fd1498Szrj     };
1859*38fd1498Szrj 
1860*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
1861*38fd1498Szrj } // namespace
1862*38fd1498Szrj 
1863*38fd1498Szrj #endif // _SHARED_PTR_BASE_H
1864