xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/bits/shared_ptr.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj // shared_ptr and weak_ptr implementation -*- 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
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_H
50*38fd1498Szrj #define _SHARED_PTR_H 1
51*38fd1498Szrj 
52*38fd1498Szrj #include <bits/shared_ptr_base.h>
53*38fd1498Szrj 
54*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
55*38fd1498Szrj {
56*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
57*38fd1498Szrj 
58*38fd1498Szrj   /**
59*38fd1498Szrj    * @addtogroup pointer_abstractions
60*38fd1498Szrj    * @{
61*38fd1498Szrj    */
62*38fd1498Szrj 
63*38fd1498Szrj   /// 20.7.2.2.11 shared_ptr I/O
64*38fd1498Szrj   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
65*38fd1498Szrj     inline std::basic_ostream<_Ch, _Tr>&
66*38fd1498Szrj     operator<<(std::basic_ostream<_Ch, _Tr>& __os,
67*38fd1498Szrj 	       const __shared_ptr<_Tp, _Lp>& __p)
68*38fd1498Szrj     {
69*38fd1498Szrj       __os << __p.get();
70*38fd1498Szrj       return __os;
71*38fd1498Szrj     }
72*38fd1498Szrj 
73*38fd1498Szrj   template<typename _Del, typename _Tp, _Lock_policy _Lp>
74*38fd1498Szrj     inline _Del*
75*38fd1498Szrj     get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
76*38fd1498Szrj     {
77*38fd1498Szrj #if __cpp_rtti
78*38fd1498Szrj       return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
79*38fd1498Szrj #else
80*38fd1498Szrj       return 0;
81*38fd1498Szrj #endif
82*38fd1498Szrj     }
83*38fd1498Szrj 
84*38fd1498Szrj   /// 20.7.2.2.10 shared_ptr get_deleter
85*38fd1498Szrj   template<typename _Del, typename _Tp>
86*38fd1498Szrj     inline _Del*
87*38fd1498Szrj     get_deleter(const shared_ptr<_Tp>& __p) noexcept
88*38fd1498Szrj     {
89*38fd1498Szrj #if __cpp_rtti
90*38fd1498Szrj       return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
91*38fd1498Szrj #else
92*38fd1498Szrj       return 0;
93*38fd1498Szrj #endif
94*38fd1498Szrj     }
95*38fd1498Szrj 
96*38fd1498Szrj   /**
97*38fd1498Szrj    *  @brief  A smart pointer with reference-counted copy semantics.
98*38fd1498Szrj    *
99*38fd1498Szrj    *  The object pointed to is deleted when the last shared_ptr pointing to
100*38fd1498Szrj    *  it is destroyed or reset.
101*38fd1498Szrj   */
102*38fd1498Szrj   template<typename _Tp>
103*38fd1498Szrj     class shared_ptr : public __shared_ptr<_Tp>
104*38fd1498Szrj     {
105*38fd1498Szrj       template<typename... _Args>
106*38fd1498Szrj 	using _Constructible = typename enable_if<
107*38fd1498Szrj 	  is_constructible<__shared_ptr<_Tp>, _Args...>::value
108*38fd1498Szrj 	>::type;
109*38fd1498Szrj 
110*38fd1498Szrj       template<typename _Arg>
111*38fd1498Szrj 	using _Assignable = typename enable_if<
112*38fd1498Szrj 	  is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr&
113*38fd1498Szrj 	>::type;
114*38fd1498Szrj 
115*38fd1498Szrj     public:
116*38fd1498Szrj 
117*38fd1498Szrj       using element_type = typename __shared_ptr<_Tp>::element_type;
118*38fd1498Szrj 
119*38fd1498Szrj #if __cplusplus > 201402L
120*38fd1498Szrj # define __cpp_lib_shared_ptr_weak_type 201606
121*38fd1498Szrj       using weak_type = weak_ptr<_Tp>;
122*38fd1498Szrj #endif
123*38fd1498Szrj       /**
124*38fd1498Szrj        *  @brief  Construct an empty %shared_ptr.
125*38fd1498Szrj        *  @post   use_count()==0 && get()==0
126*38fd1498Szrj        */
127*38fd1498Szrj       constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
128*38fd1498Szrj 
129*38fd1498Szrj       shared_ptr(const shared_ptr&) noexcept = default;
130*38fd1498Szrj 
131*38fd1498Szrj       /**
132*38fd1498Szrj        *  @brief  Construct a %shared_ptr that owns the pointer @a __p.
133*38fd1498Szrj        *  @param  __p  A pointer that is convertible to element_type*.
134*38fd1498Szrj        *  @post   use_count() == 1 && get() == __p
135*38fd1498Szrj        *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
136*38fd1498Szrj        */
137*38fd1498Szrj       template<typename _Yp, typename = _Constructible<_Yp*>>
138*38fd1498Szrj 	explicit
139*38fd1498Szrj 	shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }
140*38fd1498Szrj 
141*38fd1498Szrj       /**
142*38fd1498Szrj        *  @brief  Construct a %shared_ptr that owns the pointer @a __p
143*38fd1498Szrj        *          and the deleter @a __d.
144*38fd1498Szrj        *  @param  __p  A pointer.
145*38fd1498Szrj        *  @param  __d  A deleter.
146*38fd1498Szrj        *  @post   use_count() == 1 && get() == __p
147*38fd1498Szrj        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
148*38fd1498Szrj        *
149*38fd1498Szrj        *  Requirements: _Deleter's copy constructor and destructor must
150*38fd1498Szrj        *  not throw
151*38fd1498Szrj        *
152*38fd1498Szrj        *  __shared_ptr will release __p by calling __d(__p)
153*38fd1498Szrj        */
154*38fd1498Szrj       template<typename _Yp, typename _Deleter,
155*38fd1498Szrj 	       typename = _Constructible<_Yp*, _Deleter>>
156*38fd1498Szrj 	shared_ptr(_Yp* __p, _Deleter __d)
157*38fd1498Szrj         : __shared_ptr<_Tp>(__p, std::move(__d)) { }
158*38fd1498Szrj 
159*38fd1498Szrj       /**
160*38fd1498Szrj        *  @brief  Construct a %shared_ptr that owns a null pointer
161*38fd1498Szrj        *          and the deleter @a __d.
162*38fd1498Szrj        *  @param  __p  A null pointer constant.
163*38fd1498Szrj        *  @param  __d  A deleter.
164*38fd1498Szrj        *  @post   use_count() == 1 && get() == __p
165*38fd1498Szrj        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
166*38fd1498Szrj        *
167*38fd1498Szrj        *  Requirements: _Deleter's copy constructor and destructor must
168*38fd1498Szrj        *  not throw
169*38fd1498Szrj        *
170*38fd1498Szrj        *  The last owner will call __d(__p)
171*38fd1498Szrj        */
172*38fd1498Szrj       template<typename _Deleter>
173*38fd1498Szrj 	shared_ptr(nullptr_t __p, _Deleter __d)
174*38fd1498Szrj         : __shared_ptr<_Tp>(__p, std::move(__d)) { }
175*38fd1498Szrj 
176*38fd1498Szrj       /**
177*38fd1498Szrj        *  @brief  Construct a %shared_ptr that owns the pointer @a __p
178*38fd1498Szrj        *          and the deleter @a __d.
179*38fd1498Szrj        *  @param  __p  A pointer.
180*38fd1498Szrj        *  @param  __d  A deleter.
181*38fd1498Szrj        *  @param  __a  An allocator.
182*38fd1498Szrj        *  @post   use_count() == 1 && get() == __p
183*38fd1498Szrj        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
184*38fd1498Szrj        *
185*38fd1498Szrj        *  Requirements: _Deleter's copy constructor and destructor must
186*38fd1498Szrj        *  not throw _Alloc's copy constructor and destructor must not
187*38fd1498Szrj        *  throw.
188*38fd1498Szrj        *
189*38fd1498Szrj        *  __shared_ptr will release __p by calling __d(__p)
190*38fd1498Szrj        */
191*38fd1498Szrj       template<typename _Yp, typename _Deleter, typename _Alloc,
192*38fd1498Szrj 	       typename = _Constructible<_Yp*, _Deleter, _Alloc>>
193*38fd1498Szrj 	shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
194*38fd1498Szrj 	: __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
195*38fd1498Szrj 
196*38fd1498Szrj       /**
197*38fd1498Szrj        *  @brief  Construct a %shared_ptr that owns a null pointer
198*38fd1498Szrj        *          and the deleter @a __d.
199*38fd1498Szrj        *  @param  __p  A null pointer constant.
200*38fd1498Szrj        *  @param  __d  A deleter.
201*38fd1498Szrj        *  @param  __a  An allocator.
202*38fd1498Szrj        *  @post   use_count() == 1 && get() == __p
203*38fd1498Szrj        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
204*38fd1498Szrj        *
205*38fd1498Szrj        *  Requirements: _Deleter's copy constructor and destructor must
206*38fd1498Szrj        *  not throw _Alloc's copy constructor and destructor must not
207*38fd1498Szrj        *  throw.
208*38fd1498Szrj        *
209*38fd1498Szrj        *  The last owner will call __d(__p)
210*38fd1498Szrj        */
211*38fd1498Szrj       template<typename _Deleter, typename _Alloc>
212*38fd1498Szrj 	shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
213*38fd1498Szrj 	: __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
214*38fd1498Szrj 
215*38fd1498Szrj       // Aliasing constructor
216*38fd1498Szrj 
217*38fd1498Szrj       /**
218*38fd1498Szrj        *  @brief  Constructs a %shared_ptr instance that stores @a __p
219*38fd1498Szrj        *          and shares ownership with @a __r.
220*38fd1498Szrj        *  @param  __r  A %shared_ptr.
221*38fd1498Szrj        *  @param  __p  A pointer that will remain valid while @a *__r is valid.
222*38fd1498Szrj        *  @post   get() == __p && use_count() == __r.use_count()
223*38fd1498Szrj        *
224*38fd1498Szrj        *  This can be used to construct a @c shared_ptr to a sub-object
225*38fd1498Szrj        *  of an object managed by an existing @c shared_ptr.
226*38fd1498Szrj        *
227*38fd1498Szrj        * @code
228*38fd1498Szrj        * shared_ptr< pair<int,int> > pii(new pair<int,int>());
229*38fd1498Szrj        * shared_ptr<int> pi(pii, &pii->first);
230*38fd1498Szrj        * assert(pii.use_count() == 2);
231*38fd1498Szrj        * @endcode
232*38fd1498Szrj        */
233*38fd1498Szrj       template<typename _Yp>
234*38fd1498Szrj 	shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
235*38fd1498Szrj 	: __shared_ptr<_Tp>(__r, __p) { }
236*38fd1498Szrj 
237*38fd1498Szrj       /**
238*38fd1498Szrj        *  @brief  If @a __r is empty, constructs an empty %shared_ptr;
239*38fd1498Szrj        *          otherwise construct a %shared_ptr that shares ownership
240*38fd1498Szrj        *          with @a __r.
241*38fd1498Szrj        *  @param  __r  A %shared_ptr.
242*38fd1498Szrj        *  @post   get() == __r.get() && use_count() == __r.use_count()
243*38fd1498Szrj        */
244*38fd1498Szrj       template<typename _Yp,
245*38fd1498Szrj 	       typename = _Constructible<const shared_ptr<_Yp>&>>
246*38fd1498Szrj 	shared_ptr(const shared_ptr<_Yp>& __r) noexcept
247*38fd1498Szrj         : __shared_ptr<_Tp>(__r) { }
248*38fd1498Szrj 
249*38fd1498Szrj       /**
250*38fd1498Szrj        *  @brief  Move-constructs a %shared_ptr instance from @a __r.
251*38fd1498Szrj        *  @param  __r  A %shared_ptr rvalue.
252*38fd1498Szrj        *  @post   *this contains the old value of @a __r, @a __r is empty.
253*38fd1498Szrj        */
254*38fd1498Szrj       shared_ptr(shared_ptr&& __r) noexcept
255*38fd1498Szrj       : __shared_ptr<_Tp>(std::move(__r)) { }
256*38fd1498Szrj 
257*38fd1498Szrj       /**
258*38fd1498Szrj        *  @brief  Move-constructs a %shared_ptr instance from @a __r.
259*38fd1498Szrj        *  @param  __r  A %shared_ptr rvalue.
260*38fd1498Szrj        *  @post   *this contains the old value of @a __r, @a __r is empty.
261*38fd1498Szrj        */
262*38fd1498Szrj       template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
263*38fd1498Szrj 	shared_ptr(shared_ptr<_Yp>&& __r) noexcept
264*38fd1498Szrj 	: __shared_ptr<_Tp>(std::move(__r)) { }
265*38fd1498Szrj 
266*38fd1498Szrj       /**
267*38fd1498Szrj        *  @brief  Constructs a %shared_ptr that shares ownership with @a __r
268*38fd1498Szrj        *          and stores a copy of the pointer stored in @a __r.
269*38fd1498Szrj        *  @param  __r  A weak_ptr.
270*38fd1498Szrj        *  @post   use_count() == __r.use_count()
271*38fd1498Szrj        *  @throw  bad_weak_ptr when __r.expired(),
272*38fd1498Szrj        *          in which case the constructor has no effect.
273*38fd1498Szrj        */
274*38fd1498Szrj       template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
275*38fd1498Szrj 	explicit shared_ptr(const weak_ptr<_Yp>& __r)
276*38fd1498Szrj 	: __shared_ptr<_Tp>(__r) { }
277*38fd1498Szrj 
278*38fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
279*38fd1498Szrj #pragma GCC diagnostic push
280*38fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
281*38fd1498Szrj       template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>
282*38fd1498Szrj 	shared_ptr(auto_ptr<_Yp>&& __r);
283*38fd1498Szrj #pragma GCC diagnostic pop
284*38fd1498Szrj #endif
285*38fd1498Szrj 
286*38fd1498Szrj       // _GLIBCXX_RESOLVE_LIB_DEFECTS
287*38fd1498Szrj       // 2399. shared_ptr's constructor from unique_ptr should be constrained
288*38fd1498Szrj       template<typename _Yp, typename _Del,
289*38fd1498Szrj 	       typename = _Constructible<unique_ptr<_Yp, _Del>>>
290*38fd1498Szrj 	shared_ptr(unique_ptr<_Yp, _Del>&& __r)
291*38fd1498Szrj 	: __shared_ptr<_Tp>(std::move(__r)) { }
292*38fd1498Szrj 
293*38fd1498Szrj #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
294*38fd1498Szrj       // This non-standard constructor exists to support conversions that
295*38fd1498Szrj       // were possible in C++11 and C++14 but are ill-formed in C++17.
296*38fd1498Szrj       // If an exception is thrown this constructor has no effect.
297*38fd1498Szrj       template<typename _Yp, typename _Del,
298*38fd1498Szrj 		_Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
299*38fd1498Szrj 	shared_ptr(unique_ptr<_Yp, _Del>&& __r)
300*38fd1498Szrj 	: __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }
301*38fd1498Szrj #endif
302*38fd1498Szrj 
303*38fd1498Szrj       /**
304*38fd1498Szrj        *  @brief  Construct an empty %shared_ptr.
305*38fd1498Szrj        *  @post   use_count() == 0 && get() == nullptr
306*38fd1498Szrj        */
307*38fd1498Szrj       constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
308*38fd1498Szrj 
309*38fd1498Szrj       shared_ptr& operator=(const shared_ptr&) noexcept = default;
310*38fd1498Szrj 
311*38fd1498Szrj       template<typename _Yp>
312*38fd1498Szrj 	_Assignable<const shared_ptr<_Yp>&>
313*38fd1498Szrj 	operator=(const shared_ptr<_Yp>& __r) noexcept
314*38fd1498Szrj 	{
315*38fd1498Szrj 	  this->__shared_ptr<_Tp>::operator=(__r);
316*38fd1498Szrj 	  return *this;
317*38fd1498Szrj 	}
318*38fd1498Szrj 
319*38fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
320*38fd1498Szrj #pragma GCC diagnostic push
321*38fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
322*38fd1498Szrj       template<typename _Yp>
323*38fd1498Szrj 	_Assignable<auto_ptr<_Yp>>
324*38fd1498Szrj 	operator=(auto_ptr<_Yp>&& __r)
325*38fd1498Szrj 	{
326*38fd1498Szrj 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));
327*38fd1498Szrj 	  return *this;
328*38fd1498Szrj 	}
329*38fd1498Szrj #pragma GCC diagnostic pop
330*38fd1498Szrj #endif
331*38fd1498Szrj 
332*38fd1498Szrj       shared_ptr&
333*38fd1498Szrj       operator=(shared_ptr&& __r) noexcept
334*38fd1498Szrj       {
335*38fd1498Szrj 	this->__shared_ptr<_Tp>::operator=(std::move(__r));
336*38fd1498Szrj 	return *this;
337*38fd1498Szrj       }
338*38fd1498Szrj 
339*38fd1498Szrj       template<class _Yp>
340*38fd1498Szrj 	_Assignable<shared_ptr<_Yp>>
341*38fd1498Szrj 	operator=(shared_ptr<_Yp>&& __r) noexcept
342*38fd1498Szrj 	{
343*38fd1498Szrj 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));
344*38fd1498Szrj 	  return *this;
345*38fd1498Szrj 	}
346*38fd1498Szrj 
347*38fd1498Szrj       template<typename _Yp, typename _Del>
348*38fd1498Szrj 	_Assignable<unique_ptr<_Yp, _Del>>
349*38fd1498Szrj 	operator=(unique_ptr<_Yp, _Del>&& __r)
350*38fd1498Szrj 	{
351*38fd1498Szrj 	  this->__shared_ptr<_Tp>::operator=(std::move(__r));
352*38fd1498Szrj 	  return *this;
353*38fd1498Szrj 	}
354*38fd1498Szrj 
355*38fd1498Szrj     private:
356*38fd1498Szrj       // This constructor is non-standard, it is used by allocate_shared.
357*38fd1498Szrj       template<typename _Alloc, typename... _Args>
358*38fd1498Szrj 	shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
359*38fd1498Szrj 		   _Args&&... __args)
360*38fd1498Szrj 	: __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
361*38fd1498Szrj 	{ }
362*38fd1498Szrj 
363*38fd1498Szrj       template<typename _Yp, typename _Alloc, typename... _Args>
364*38fd1498Szrj 	friend shared_ptr<_Yp>
365*38fd1498Szrj 	allocate_shared(const _Alloc& __a, _Args&&... __args);
366*38fd1498Szrj 
367*38fd1498Szrj       // This constructor is non-standard, it is used by weak_ptr::lock().
368*38fd1498Szrj       shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
369*38fd1498Szrj       : __shared_ptr<_Tp>(__r, std::nothrow) { }
370*38fd1498Szrj 
371*38fd1498Szrj       friend class weak_ptr<_Tp>;
372*38fd1498Szrj     };
373*38fd1498Szrj 
374*38fd1498Szrj #if __cpp_deduction_guides >= 201606
375*38fd1498Szrj   template<typename _Tp>
376*38fd1498Szrj     shared_ptr(weak_ptr<_Tp>) ->  shared_ptr<_Tp>;
377*38fd1498Szrj   template<typename _Tp, typename _Del>
378*38fd1498Szrj     shared_ptr(unique_ptr<_Tp, _Del>) ->  shared_ptr<_Tp>;
379*38fd1498Szrj #endif
380*38fd1498Szrj 
381*38fd1498Szrj   // 20.7.2.2.7 shared_ptr comparisons
382*38fd1498Szrj   template<typename _Tp, typename _Up>
383*38fd1498Szrj     inline bool
384*38fd1498Szrj     operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
385*38fd1498Szrj     { return __a.get() == __b.get(); }
386*38fd1498Szrj 
387*38fd1498Szrj   template<typename _Tp>
388*38fd1498Szrj     inline bool
389*38fd1498Szrj     operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
390*38fd1498Szrj     { return !__a; }
391*38fd1498Szrj 
392*38fd1498Szrj   template<typename _Tp>
393*38fd1498Szrj     inline bool
394*38fd1498Szrj     operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
395*38fd1498Szrj     { return !__a; }
396*38fd1498Szrj 
397*38fd1498Szrj   template<typename _Tp, typename _Up>
398*38fd1498Szrj     inline bool
399*38fd1498Szrj     operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
400*38fd1498Szrj     { return __a.get() != __b.get(); }
401*38fd1498Szrj 
402*38fd1498Szrj   template<typename _Tp>
403*38fd1498Szrj     inline bool
404*38fd1498Szrj     operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
405*38fd1498Szrj     { return (bool)__a; }
406*38fd1498Szrj 
407*38fd1498Szrj   template<typename _Tp>
408*38fd1498Szrj     inline bool
409*38fd1498Szrj     operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
410*38fd1498Szrj     { return (bool)__a; }
411*38fd1498Szrj 
412*38fd1498Szrj   template<typename _Tp, typename _Up>
413*38fd1498Szrj     inline bool
414*38fd1498Szrj     operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
415*38fd1498Szrj     {
416*38fd1498Szrj       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
417*38fd1498Szrj       using _Up_elt = typename shared_ptr<_Up>::element_type;
418*38fd1498Szrj       using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
419*38fd1498Szrj       return less<_Vp>()(__a.get(), __b.get());
420*38fd1498Szrj     }
421*38fd1498Szrj 
422*38fd1498Szrj   template<typename _Tp>
423*38fd1498Szrj     inline bool
424*38fd1498Szrj     operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
425*38fd1498Szrj     {
426*38fd1498Szrj       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
427*38fd1498Szrj       return less<_Tp_elt*>()(__a.get(), nullptr);
428*38fd1498Szrj     }
429*38fd1498Szrj 
430*38fd1498Szrj   template<typename _Tp>
431*38fd1498Szrj     inline bool
432*38fd1498Szrj     operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
433*38fd1498Szrj     {
434*38fd1498Szrj       using _Tp_elt = typename shared_ptr<_Tp>::element_type;
435*38fd1498Szrj       return less<_Tp_elt*>()(nullptr, __a.get());
436*38fd1498Szrj     }
437*38fd1498Szrj 
438*38fd1498Szrj   template<typename _Tp, typename _Up>
439*38fd1498Szrj     inline bool
440*38fd1498Szrj     operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
441*38fd1498Szrj     { return !(__b < __a); }
442*38fd1498Szrj 
443*38fd1498Szrj   template<typename _Tp>
444*38fd1498Szrj     inline bool
445*38fd1498Szrj     operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
446*38fd1498Szrj     { return !(nullptr < __a); }
447*38fd1498Szrj 
448*38fd1498Szrj   template<typename _Tp>
449*38fd1498Szrj     inline bool
450*38fd1498Szrj     operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
451*38fd1498Szrj     { return !(__a < nullptr); }
452*38fd1498Szrj 
453*38fd1498Szrj   template<typename _Tp, typename _Up>
454*38fd1498Szrj     inline bool
455*38fd1498Szrj     operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
456*38fd1498Szrj     { return (__b < __a); }
457*38fd1498Szrj 
458*38fd1498Szrj   template<typename _Tp>
459*38fd1498Szrj     inline bool
460*38fd1498Szrj     operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
461*38fd1498Szrj     { return nullptr < __a; }
462*38fd1498Szrj 
463*38fd1498Szrj   template<typename _Tp>
464*38fd1498Szrj     inline bool
465*38fd1498Szrj     operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
466*38fd1498Szrj     { return __a < nullptr; }
467*38fd1498Szrj 
468*38fd1498Szrj   template<typename _Tp, typename _Up>
469*38fd1498Szrj     inline bool
470*38fd1498Szrj     operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
471*38fd1498Szrj     { return !(__a < __b); }
472*38fd1498Szrj 
473*38fd1498Szrj   template<typename _Tp>
474*38fd1498Szrj     inline bool
475*38fd1498Szrj     operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
476*38fd1498Szrj     { return !(__a < nullptr); }
477*38fd1498Szrj 
478*38fd1498Szrj   template<typename _Tp>
479*38fd1498Szrj     inline bool
480*38fd1498Szrj     operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
481*38fd1498Szrj     { return !(nullptr < __a); }
482*38fd1498Szrj 
483*38fd1498Szrj   template<typename _Tp>
484*38fd1498Szrj     struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>>
485*38fd1498Szrj     { };
486*38fd1498Szrj 
487*38fd1498Szrj   // 20.7.2.2.8 shared_ptr specialized algorithms.
488*38fd1498Szrj   template<typename _Tp>
489*38fd1498Szrj     inline void
490*38fd1498Szrj     swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
491*38fd1498Szrj     { __a.swap(__b); }
492*38fd1498Szrj 
493*38fd1498Szrj   // 20.7.2.2.9 shared_ptr casts.
494*38fd1498Szrj   template<typename _Tp, typename _Up>
495*38fd1498Szrj     inline shared_ptr<_Tp>
496*38fd1498Szrj     static_pointer_cast(const shared_ptr<_Up>& __r) noexcept
497*38fd1498Szrj     {
498*38fd1498Szrj       using _Sp = shared_ptr<_Tp>;
499*38fd1498Szrj       return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
500*38fd1498Szrj     }
501*38fd1498Szrj 
502*38fd1498Szrj   template<typename _Tp, typename _Up>
503*38fd1498Szrj     inline shared_ptr<_Tp>
504*38fd1498Szrj     const_pointer_cast(const shared_ptr<_Up>& __r) noexcept
505*38fd1498Szrj     {
506*38fd1498Szrj       using _Sp = shared_ptr<_Tp>;
507*38fd1498Szrj       return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
508*38fd1498Szrj     }
509*38fd1498Szrj 
510*38fd1498Szrj   template<typename _Tp, typename _Up>
511*38fd1498Szrj     inline shared_ptr<_Tp>
512*38fd1498Szrj     dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept
513*38fd1498Szrj     {
514*38fd1498Szrj       using _Sp = shared_ptr<_Tp>;
515*38fd1498Szrj       if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
516*38fd1498Szrj 	return _Sp(__r, __p);
517*38fd1498Szrj       return _Sp();
518*38fd1498Szrj     }
519*38fd1498Szrj 
520*38fd1498Szrj #if __cplusplus > 201402L
521*38fd1498Szrj   template<typename _Tp, typename _Up>
522*38fd1498Szrj     inline shared_ptr<_Tp>
523*38fd1498Szrj     reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
524*38fd1498Szrj     {
525*38fd1498Szrj       using _Sp = shared_ptr<_Tp>;
526*38fd1498Szrj       return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
527*38fd1498Szrj     }
528*38fd1498Szrj #endif
529*38fd1498Szrj 
530*38fd1498Szrj   /**
531*38fd1498Szrj    *  @brief  A smart pointer with weak semantics.
532*38fd1498Szrj    *
533*38fd1498Szrj    *  With forwarding constructors and assignment operators.
534*38fd1498Szrj    */
535*38fd1498Szrj   template<typename _Tp>
536*38fd1498Szrj     class weak_ptr : public __weak_ptr<_Tp>
537*38fd1498Szrj     {
538*38fd1498Szrj       template<typename _Arg>
539*38fd1498Szrj 	using _Constructible = typename enable_if<
540*38fd1498Szrj 	  is_constructible<__weak_ptr<_Tp>, _Arg>::value
541*38fd1498Szrj 	>::type;
542*38fd1498Szrj 
543*38fd1498Szrj       template<typename _Arg>
544*38fd1498Szrj 	using _Assignable = typename enable_if<
545*38fd1498Szrj 	  is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&
546*38fd1498Szrj 	>::type;
547*38fd1498Szrj 
548*38fd1498Szrj     public:
549*38fd1498Szrj       constexpr weak_ptr() noexcept = default;
550*38fd1498Szrj 
551*38fd1498Szrj       template<typename _Yp,
552*38fd1498Szrj 	       typename = _Constructible<const shared_ptr<_Yp>&>>
553*38fd1498Szrj 	weak_ptr(const shared_ptr<_Yp>& __r) noexcept
554*38fd1498Szrj 	: __weak_ptr<_Tp>(__r) { }
555*38fd1498Szrj 
556*38fd1498Szrj       weak_ptr(const weak_ptr&) noexcept = default;
557*38fd1498Szrj 
558*38fd1498Szrj       template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
559*38fd1498Szrj 	weak_ptr(const weak_ptr<_Yp>& __r) noexcept
560*38fd1498Szrj 	: __weak_ptr<_Tp>(__r) { }
561*38fd1498Szrj 
562*38fd1498Szrj       weak_ptr(weak_ptr&&) noexcept = default;
563*38fd1498Szrj 
564*38fd1498Szrj       template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>
565*38fd1498Szrj 	weak_ptr(weak_ptr<_Yp>&& __r) noexcept
566*38fd1498Szrj 	: __weak_ptr<_Tp>(std::move(__r)) { }
567*38fd1498Szrj 
568*38fd1498Szrj       weak_ptr&
569*38fd1498Szrj       operator=(const weak_ptr& __r) noexcept = default;
570*38fd1498Szrj 
571*38fd1498Szrj       template<typename _Yp>
572*38fd1498Szrj 	_Assignable<const weak_ptr<_Yp>&>
573*38fd1498Szrj 	operator=(const weak_ptr<_Yp>& __r) noexcept
574*38fd1498Szrj 	{
575*38fd1498Szrj 	  this->__weak_ptr<_Tp>::operator=(__r);
576*38fd1498Szrj 	  return *this;
577*38fd1498Szrj 	}
578*38fd1498Szrj 
579*38fd1498Szrj       template<typename _Yp>
580*38fd1498Szrj 	_Assignable<const shared_ptr<_Yp>&>
581*38fd1498Szrj 	operator=(const shared_ptr<_Yp>& __r) noexcept
582*38fd1498Szrj 	{
583*38fd1498Szrj 	  this->__weak_ptr<_Tp>::operator=(__r);
584*38fd1498Szrj 	  return *this;
585*38fd1498Szrj 	}
586*38fd1498Szrj 
587*38fd1498Szrj       weak_ptr&
588*38fd1498Szrj       operator=(weak_ptr&& __r) noexcept = default;
589*38fd1498Szrj 
590*38fd1498Szrj       template<typename _Yp>
591*38fd1498Szrj 	_Assignable<weak_ptr<_Yp>>
592*38fd1498Szrj 	operator=(weak_ptr<_Yp>&& __r) noexcept
593*38fd1498Szrj 	{
594*38fd1498Szrj 	  this->__weak_ptr<_Tp>::operator=(std::move(__r));
595*38fd1498Szrj 	  return *this;
596*38fd1498Szrj 	}
597*38fd1498Szrj 
598*38fd1498Szrj       shared_ptr<_Tp>
599*38fd1498Szrj       lock() const noexcept
600*38fd1498Szrj       { return shared_ptr<_Tp>(*this, std::nothrow); }
601*38fd1498Szrj     };
602*38fd1498Szrj 
603*38fd1498Szrj #if __cpp_deduction_guides >= 201606
604*38fd1498Szrj   template<typename _Tp>
605*38fd1498Szrj     weak_ptr(shared_ptr<_Tp>) ->  weak_ptr<_Tp>;
606*38fd1498Szrj #endif
607*38fd1498Szrj 
608*38fd1498Szrj   // 20.7.2.3.6 weak_ptr specialized algorithms.
609*38fd1498Szrj   template<typename _Tp>
610*38fd1498Szrj     inline void
611*38fd1498Szrj     swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
612*38fd1498Szrj     { __a.swap(__b); }
613*38fd1498Szrj 
614*38fd1498Szrj 
615*38fd1498Szrj   /// Primary template owner_less
616*38fd1498Szrj   template<typename _Tp = void>
617*38fd1498Szrj     struct owner_less;
618*38fd1498Szrj 
619*38fd1498Szrj   /// Void specialization of owner_less
620*38fd1498Szrj   template<>
621*38fd1498Szrj     struct owner_less<void> : _Sp_owner_less<void, void>
622*38fd1498Szrj     { };
623*38fd1498Szrj 
624*38fd1498Szrj   /// Partial specialization of owner_less for shared_ptr.
625*38fd1498Szrj   template<typename _Tp>
626*38fd1498Szrj     struct owner_less<shared_ptr<_Tp>>
627*38fd1498Szrj     : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
628*38fd1498Szrj     { };
629*38fd1498Szrj 
630*38fd1498Szrj   /// Partial specialization of owner_less for weak_ptr.
631*38fd1498Szrj   template<typename _Tp>
632*38fd1498Szrj     struct owner_less<weak_ptr<_Tp>>
633*38fd1498Szrj     : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
634*38fd1498Szrj     { };
635*38fd1498Szrj 
636*38fd1498Szrj   /**
637*38fd1498Szrj    *  @brief Base class allowing use of member function shared_from_this.
638*38fd1498Szrj    */
639*38fd1498Szrj   template<typename _Tp>
640*38fd1498Szrj     class enable_shared_from_this
641*38fd1498Szrj     {
642*38fd1498Szrj     protected:
643*38fd1498Szrj       constexpr enable_shared_from_this() noexcept { }
644*38fd1498Szrj 
645*38fd1498Szrj       enable_shared_from_this(const enable_shared_from_this&) noexcept { }
646*38fd1498Szrj 
647*38fd1498Szrj       enable_shared_from_this&
648*38fd1498Szrj       operator=(const enable_shared_from_this&) noexcept
649*38fd1498Szrj       { return *this; }
650*38fd1498Szrj 
651*38fd1498Szrj       ~enable_shared_from_this() { }
652*38fd1498Szrj 
653*38fd1498Szrj     public:
654*38fd1498Szrj       shared_ptr<_Tp>
655*38fd1498Szrj       shared_from_this()
656*38fd1498Szrj       { return shared_ptr<_Tp>(this->_M_weak_this); }
657*38fd1498Szrj 
658*38fd1498Szrj       shared_ptr<const _Tp>
659*38fd1498Szrj       shared_from_this() const
660*38fd1498Szrj       { return shared_ptr<const _Tp>(this->_M_weak_this); }
661*38fd1498Szrj 
662*38fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
663*38fd1498Szrj #define __cpp_lib_enable_shared_from_this 201603
664*38fd1498Szrj       weak_ptr<_Tp>
665*38fd1498Szrj       weak_from_this() noexcept
666*38fd1498Szrj       { return this->_M_weak_this; }
667*38fd1498Szrj 
668*38fd1498Szrj       weak_ptr<const _Tp>
669*38fd1498Szrj       weak_from_this() const noexcept
670*38fd1498Szrj       { return this->_M_weak_this; }
671*38fd1498Szrj #endif
672*38fd1498Szrj 
673*38fd1498Szrj     private:
674*38fd1498Szrj       template<typename _Tp1>
675*38fd1498Szrj 	void
676*38fd1498Szrj 	_M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
677*38fd1498Szrj 	{ _M_weak_this._M_assign(__p, __n); }
678*38fd1498Szrj 
679*38fd1498Szrj       // Found by ADL when this is an associated class.
680*38fd1498Szrj       friend const enable_shared_from_this*
681*38fd1498Szrj       __enable_shared_from_this_base(const __shared_count<>&,
682*38fd1498Szrj 				     const enable_shared_from_this* __p)
683*38fd1498Szrj       { return __p; }
684*38fd1498Szrj 
685*38fd1498Szrj       template<typename, _Lock_policy>
686*38fd1498Szrj 	friend class __shared_ptr;
687*38fd1498Szrj 
688*38fd1498Szrj       mutable weak_ptr<_Tp>  _M_weak_this;
689*38fd1498Szrj     };
690*38fd1498Szrj 
691*38fd1498Szrj   /**
692*38fd1498Szrj    *  @brief  Create an object that is owned by a shared_ptr.
693*38fd1498Szrj    *  @param  __a     An allocator.
694*38fd1498Szrj    *  @param  __args  Arguments for the @a _Tp object's constructor.
695*38fd1498Szrj    *  @return A shared_ptr that owns the newly created object.
696*38fd1498Szrj    *  @throw  An exception thrown from @a _Alloc::allocate or from the
697*38fd1498Szrj    *          constructor of @a _Tp.
698*38fd1498Szrj    *
699*38fd1498Szrj    *  A copy of @a __a will be used to allocate memory for the shared_ptr
700*38fd1498Szrj    *  and the new object.
701*38fd1498Szrj    */
702*38fd1498Szrj   template<typename _Tp, typename _Alloc, typename... _Args>
703*38fd1498Szrj     inline shared_ptr<_Tp>
704*38fd1498Szrj     allocate_shared(const _Alloc& __a, _Args&&... __args)
705*38fd1498Szrj     {
706*38fd1498Szrj       return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a,
707*38fd1498Szrj 			     std::forward<_Args>(__args)...);
708*38fd1498Szrj     }
709*38fd1498Szrj 
710*38fd1498Szrj   /**
711*38fd1498Szrj    *  @brief  Create an object that is owned by a shared_ptr.
712*38fd1498Szrj    *  @param  __args  Arguments for the @a _Tp object's constructor.
713*38fd1498Szrj    *  @return A shared_ptr that owns the newly created object.
714*38fd1498Szrj    *  @throw  std::bad_alloc, or an exception thrown from the
715*38fd1498Szrj    *          constructor of @a _Tp.
716*38fd1498Szrj    */
717*38fd1498Szrj   template<typename _Tp, typename... _Args>
718*38fd1498Szrj     inline shared_ptr<_Tp>
719*38fd1498Szrj     make_shared(_Args&&... __args)
720*38fd1498Szrj     {
721*38fd1498Szrj       typedef typename std::remove_const<_Tp>::type _Tp_nc;
722*38fd1498Szrj       return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
723*38fd1498Szrj 				       std::forward<_Args>(__args)...);
724*38fd1498Szrj     }
725*38fd1498Szrj 
726*38fd1498Szrj   /// std::hash specialization for shared_ptr.
727*38fd1498Szrj   template<typename _Tp>
728*38fd1498Szrj     struct hash<shared_ptr<_Tp>>
729*38fd1498Szrj     : public __hash_base<size_t, shared_ptr<_Tp>>
730*38fd1498Szrj     {
731*38fd1498Szrj       size_t
732*38fd1498Szrj       operator()(const shared_ptr<_Tp>& __s) const noexcept
733*38fd1498Szrj       {
734*38fd1498Szrj 	return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get());
735*38fd1498Szrj       }
736*38fd1498Szrj     };
737*38fd1498Szrj 
738*38fd1498Szrj   // @} group pointer_abstractions
739*38fd1498Szrj 
740*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
741*38fd1498Szrj } // namespace
742*38fd1498Szrj 
743*38fd1498Szrj #endif // _SHARED_PTR_H
744