1*e4b17023SJohn Marino // shared_ptr and weak_ptr implementation -*- C++ -*-
2*e4b17023SJohn Marino
3*e4b17023SJohn Marino // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4*e4b17023SJohn Marino //
5*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free
6*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
7*e4b17023SJohn Marino // terms of the GNU General Public License as published by the
8*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
9*e4b17023SJohn Marino // any later version.
10*e4b17023SJohn Marino
11*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
12*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*e4b17023SJohn Marino // GNU General Public License for more details.
15*e4b17023SJohn Marino
16*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
17*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
18*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
19*e4b17023SJohn Marino
20*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
21*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
22*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
24*e4b17023SJohn Marino
25*e4b17023SJohn Marino // GCC Note: Based on files from version 1.32.0 of the Boost library.
26*e4b17023SJohn Marino
27*e4b17023SJohn Marino // shared_count.hpp
28*e4b17023SJohn Marino // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
29*e4b17023SJohn Marino
30*e4b17023SJohn Marino // shared_ptr.hpp
31*e4b17023SJohn Marino // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
32*e4b17023SJohn Marino // Copyright (C) 2001, 2002, 2003 Peter Dimov
33*e4b17023SJohn Marino
34*e4b17023SJohn Marino // weak_ptr.hpp
35*e4b17023SJohn Marino // Copyright (C) 2001, 2002, 2003 Peter Dimov
36*e4b17023SJohn Marino
37*e4b17023SJohn Marino // enable_shared_from_this.hpp
38*e4b17023SJohn Marino // Copyright (C) 2002 Peter Dimov
39*e4b17023SJohn Marino
40*e4b17023SJohn Marino // Distributed under the Boost Software License, Version 1.0. (See
41*e4b17023SJohn Marino // accompanying file LICENSE_1_0.txt or copy at
42*e4b17023SJohn Marino // http://www.boost.org/LICENSE_1_0.txt)
43*e4b17023SJohn Marino
44*e4b17023SJohn Marino /** @file bits/shared_ptr.h
45*e4b17023SJohn Marino * This is an internal header file, included by other library headers.
46*e4b17023SJohn Marino * Do not attempt to use it directly. @headername{memory}
47*e4b17023SJohn Marino */
48*e4b17023SJohn Marino
49*e4b17023SJohn Marino #ifndef _SHARED_PTR_H
50*e4b17023SJohn Marino #define _SHARED_PTR_H 1
51*e4b17023SJohn Marino
52*e4b17023SJohn Marino #include <bits/shared_ptr_base.h>
53*e4b17023SJohn Marino
_GLIBCXX_VISIBILITY(default)54*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
55*e4b17023SJohn Marino {
56*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
57*e4b17023SJohn Marino
58*e4b17023SJohn Marino /**
59*e4b17023SJohn Marino * @addtogroup pointer_abstractions
60*e4b17023SJohn Marino * @{
61*e4b17023SJohn Marino */
62*e4b17023SJohn Marino
63*e4b17023SJohn Marino /// 2.2.3.7 shared_ptr I/O
64*e4b17023SJohn Marino template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
65*e4b17023SJohn Marino inline std::basic_ostream<_Ch, _Tr>&
66*e4b17023SJohn Marino operator<<(std::basic_ostream<_Ch, _Tr>& __os,
67*e4b17023SJohn Marino const __shared_ptr<_Tp, _Lp>& __p)
68*e4b17023SJohn Marino {
69*e4b17023SJohn Marino __os << __p.get();
70*e4b17023SJohn Marino return __os;
71*e4b17023SJohn Marino }
72*e4b17023SJohn Marino
73*e4b17023SJohn Marino /// 2.2.3.10 shared_ptr get_deleter (experimental)
74*e4b17023SJohn Marino template<typename _Del, typename _Tp, _Lock_policy _Lp>
75*e4b17023SJohn Marino inline _Del*
76*e4b17023SJohn Marino get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
77*e4b17023SJohn Marino {
78*e4b17023SJohn Marino #ifdef __GXX_RTTI
79*e4b17023SJohn Marino return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
80*e4b17023SJohn Marino #else
81*e4b17023SJohn Marino return 0;
82*e4b17023SJohn Marino #endif
83*e4b17023SJohn Marino }
84*e4b17023SJohn Marino
85*e4b17023SJohn Marino
86*e4b17023SJohn Marino /**
87*e4b17023SJohn Marino * @brief A smart pointer with reference-counted copy semantics.
88*e4b17023SJohn Marino *
89*e4b17023SJohn Marino * The object pointed to is deleted when the last shared_ptr pointing to
90*e4b17023SJohn Marino * it is destroyed or reset.
91*e4b17023SJohn Marino */
92*e4b17023SJohn Marino template<typename _Tp>
93*e4b17023SJohn Marino class shared_ptr : public __shared_ptr<_Tp>
94*e4b17023SJohn Marino {
95*e4b17023SJohn Marino public:
96*e4b17023SJohn Marino /**
97*e4b17023SJohn Marino * @brief Construct an empty %shared_ptr.
98*e4b17023SJohn Marino * @post use_count()==0 && get()==0
99*e4b17023SJohn Marino */
100*e4b17023SJohn Marino constexpr shared_ptr() noexcept
101*e4b17023SJohn Marino : __shared_ptr<_Tp>() { }
102*e4b17023SJohn Marino
103*e4b17023SJohn Marino shared_ptr(const shared_ptr&) noexcept = default;
104*e4b17023SJohn Marino
105*e4b17023SJohn Marino /**
106*e4b17023SJohn Marino * @brief Construct a %shared_ptr that owns the pointer @a __p.
107*e4b17023SJohn Marino * @param __p A pointer that is convertible to element_type*.
108*e4b17023SJohn Marino * @post use_count() == 1 && get() == __p
109*e4b17023SJohn Marino * @throw std::bad_alloc, in which case @c delete @a __p is called.
110*e4b17023SJohn Marino */
111*e4b17023SJohn Marino template<typename _Tp1>
112*e4b17023SJohn Marino explicit shared_ptr(_Tp1* __p)
113*e4b17023SJohn Marino : __shared_ptr<_Tp>(__p) { }
114*e4b17023SJohn Marino
115*e4b17023SJohn Marino /**
116*e4b17023SJohn Marino * @brief Construct a %shared_ptr that owns the pointer @a __p
117*e4b17023SJohn Marino * and the deleter @a __d.
118*e4b17023SJohn Marino * @param __p A pointer.
119*e4b17023SJohn Marino * @param __d A deleter.
120*e4b17023SJohn Marino * @post use_count() == 1 && get() == __p
121*e4b17023SJohn Marino * @throw std::bad_alloc, in which case @a __d(__p) is called.
122*e4b17023SJohn Marino *
123*e4b17023SJohn Marino * Requirements: _Deleter's copy constructor and destructor must
124*e4b17023SJohn Marino * not throw
125*e4b17023SJohn Marino *
126*e4b17023SJohn Marino * __shared_ptr will release __p by calling __d(__p)
127*e4b17023SJohn Marino */
128*e4b17023SJohn Marino template<typename _Tp1, typename _Deleter>
129*e4b17023SJohn Marino shared_ptr(_Tp1* __p, _Deleter __d)
130*e4b17023SJohn Marino : __shared_ptr<_Tp>(__p, __d) { }
131*e4b17023SJohn Marino
132*e4b17023SJohn Marino /**
133*e4b17023SJohn Marino * @brief Construct a %shared_ptr that owns a null pointer
134*e4b17023SJohn Marino * and the deleter @a __d.
135*e4b17023SJohn Marino * @param __p A null pointer constant.
136*e4b17023SJohn Marino * @param __d A deleter.
137*e4b17023SJohn Marino * @post use_count() == 1 && get() == __p
138*e4b17023SJohn Marino * @throw std::bad_alloc, in which case @a __d(__p) is called.
139*e4b17023SJohn Marino *
140*e4b17023SJohn Marino * Requirements: _Deleter's copy constructor and destructor must
141*e4b17023SJohn Marino * not throw
142*e4b17023SJohn Marino *
143*e4b17023SJohn Marino * The last owner will call __d(__p)
144*e4b17023SJohn Marino */
145*e4b17023SJohn Marino template<typename _Deleter>
146*e4b17023SJohn Marino shared_ptr(nullptr_t __p, _Deleter __d)
147*e4b17023SJohn Marino : __shared_ptr<_Tp>(__p, __d) { }
148*e4b17023SJohn Marino
149*e4b17023SJohn Marino /**
150*e4b17023SJohn Marino * @brief Construct a %shared_ptr that owns the pointer @a __p
151*e4b17023SJohn Marino * and the deleter @a __d.
152*e4b17023SJohn Marino * @param __p A pointer.
153*e4b17023SJohn Marino * @param __d A deleter.
154*e4b17023SJohn Marino * @param __a An allocator.
155*e4b17023SJohn Marino * @post use_count() == 1 && get() == __p
156*e4b17023SJohn Marino * @throw std::bad_alloc, in which case @a __d(__p) is called.
157*e4b17023SJohn Marino *
158*e4b17023SJohn Marino * Requirements: _Deleter's copy constructor and destructor must
159*e4b17023SJohn Marino * not throw _Alloc's copy constructor and destructor must not
160*e4b17023SJohn Marino * throw.
161*e4b17023SJohn Marino *
162*e4b17023SJohn Marino * __shared_ptr will release __p by calling __d(__p)
163*e4b17023SJohn Marino */
164*e4b17023SJohn Marino template<typename _Tp1, typename _Deleter, typename _Alloc>
165*e4b17023SJohn Marino shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
166*e4b17023SJohn Marino : __shared_ptr<_Tp>(__p, __d, std::move(__a)) { }
167*e4b17023SJohn Marino
168*e4b17023SJohn Marino /**
169*e4b17023SJohn Marino * @brief Construct a %shared_ptr that owns a null pointer
170*e4b17023SJohn Marino * and the deleter @a __d.
171*e4b17023SJohn Marino * @param __p A null pointer constant.
172*e4b17023SJohn Marino * @param __d A deleter.
173*e4b17023SJohn Marino * @param __a An allocator.
174*e4b17023SJohn Marino * @post use_count() == 1 && get() == __p
175*e4b17023SJohn Marino * @throw std::bad_alloc, in which case @a __d(__p) is called.
176*e4b17023SJohn Marino *
177*e4b17023SJohn Marino * Requirements: _Deleter's copy constructor and destructor must
178*e4b17023SJohn Marino * not throw _Alloc's copy constructor and destructor must not
179*e4b17023SJohn Marino * throw.
180*e4b17023SJohn Marino *
181*e4b17023SJohn Marino * The last owner will call __d(__p)
182*e4b17023SJohn Marino */
183*e4b17023SJohn Marino template<typename _Deleter, typename _Alloc>
184*e4b17023SJohn Marino shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
185*e4b17023SJohn Marino : __shared_ptr<_Tp>(__p, __d, std::move(__a)) { }
186*e4b17023SJohn Marino
187*e4b17023SJohn Marino // Aliasing constructor
188*e4b17023SJohn Marino
189*e4b17023SJohn Marino /**
190*e4b17023SJohn Marino * @brief Constructs a %shared_ptr instance that stores @a __p
191*e4b17023SJohn Marino * and shares ownership with @a __r.
192*e4b17023SJohn Marino * @param __r A %shared_ptr.
193*e4b17023SJohn Marino * @param __p A pointer that will remain valid while @a *__r is valid.
194*e4b17023SJohn Marino * @post get() == __p && use_count() == __r.use_count()
195*e4b17023SJohn Marino *
196*e4b17023SJohn Marino * This can be used to construct a @c shared_ptr to a sub-object
197*e4b17023SJohn Marino * of an object managed by an existing @c shared_ptr.
198*e4b17023SJohn Marino *
199*e4b17023SJohn Marino * @code
200*e4b17023SJohn Marino * shared_ptr< pair<int,int> > pii(new pair<int,int>());
201*e4b17023SJohn Marino * shared_ptr<int> pi(pii, &pii->first);
202*e4b17023SJohn Marino * assert(pii.use_count() == 2);
203*e4b17023SJohn Marino * @endcode
204*e4b17023SJohn Marino */
205*e4b17023SJohn Marino template<typename _Tp1>
206*e4b17023SJohn Marino shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p) noexcept
207*e4b17023SJohn Marino : __shared_ptr<_Tp>(__r, __p) { }
208*e4b17023SJohn Marino
209*e4b17023SJohn Marino /**
210*e4b17023SJohn Marino * @brief If @a __r is empty, constructs an empty %shared_ptr;
211*e4b17023SJohn Marino * otherwise construct a %shared_ptr that shares ownership
212*e4b17023SJohn Marino * with @a __r.
213*e4b17023SJohn Marino * @param __r A %shared_ptr.
214*e4b17023SJohn Marino * @post get() == __r.get() && use_count() == __r.use_count()
215*e4b17023SJohn Marino */
216*e4b17023SJohn Marino template<typename _Tp1, typename = typename
217*e4b17023SJohn Marino std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
218*e4b17023SJohn Marino shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
219*e4b17023SJohn Marino : __shared_ptr<_Tp>(__r) { }
220*e4b17023SJohn Marino
221*e4b17023SJohn Marino /**
222*e4b17023SJohn Marino * @brief Move-constructs a %shared_ptr instance from @a __r.
223*e4b17023SJohn Marino * @param __r A %shared_ptr rvalue.
224*e4b17023SJohn Marino * @post *this contains the old value of @a __r, @a __r is empty.
225*e4b17023SJohn Marino */
226*e4b17023SJohn Marino shared_ptr(shared_ptr&& __r) noexcept
227*e4b17023SJohn Marino : __shared_ptr<_Tp>(std::move(__r)) { }
228*e4b17023SJohn Marino
229*e4b17023SJohn Marino /**
230*e4b17023SJohn Marino * @brief Move-constructs a %shared_ptr instance from @a __r.
231*e4b17023SJohn Marino * @param __r A %shared_ptr rvalue.
232*e4b17023SJohn Marino * @post *this contains the old value of @a __r, @a __r is empty.
233*e4b17023SJohn Marino */
234*e4b17023SJohn Marino template<typename _Tp1, typename = typename
235*e4b17023SJohn Marino std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
236*e4b17023SJohn Marino shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
237*e4b17023SJohn Marino : __shared_ptr<_Tp>(std::move(__r)) { }
238*e4b17023SJohn Marino
239*e4b17023SJohn Marino /**
240*e4b17023SJohn Marino * @brief Constructs a %shared_ptr that shares ownership with @a __r
241*e4b17023SJohn Marino * and stores a copy of the pointer stored in @a __r.
242*e4b17023SJohn Marino * @param __r A weak_ptr.
243*e4b17023SJohn Marino * @post use_count() == __r.use_count()
244*e4b17023SJohn Marino * @throw bad_weak_ptr when __r.expired(),
245*e4b17023SJohn Marino * in which case the constructor has no effect.
246*e4b17023SJohn Marino */
247*e4b17023SJohn Marino template<typename _Tp1>
248*e4b17023SJohn Marino explicit shared_ptr(const weak_ptr<_Tp1>& __r)
249*e4b17023SJohn Marino : __shared_ptr<_Tp>(__r) { }
250*e4b17023SJohn Marino
251*e4b17023SJohn Marino #if _GLIBCXX_USE_DEPRECATED
252*e4b17023SJohn Marino template<typename _Tp1>
253*e4b17023SJohn Marino shared_ptr(std::auto_ptr<_Tp1>&& __r)
254*e4b17023SJohn Marino : __shared_ptr<_Tp>(std::move(__r)) { }
255*e4b17023SJohn Marino #endif
256*e4b17023SJohn Marino
257*e4b17023SJohn Marino template<typename _Tp1, typename _Del>
258*e4b17023SJohn Marino shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
259*e4b17023SJohn Marino : __shared_ptr<_Tp>(std::move(__r)) { }
260*e4b17023SJohn Marino
261*e4b17023SJohn Marino /**
262*e4b17023SJohn Marino * @brief Construct an empty %shared_ptr.
263*e4b17023SJohn Marino * @param __p A null pointer constant.
264*e4b17023SJohn Marino * @post use_count() == 0 && get() == nullptr
265*e4b17023SJohn Marino */
266*e4b17023SJohn Marino constexpr shared_ptr(nullptr_t __p) noexcept
267*e4b17023SJohn Marino : __shared_ptr<_Tp>(__p) { }
268*e4b17023SJohn Marino
269*e4b17023SJohn Marino shared_ptr& operator=(const shared_ptr&) noexcept = default;
270*e4b17023SJohn Marino
271*e4b17023SJohn Marino template<typename _Tp1>
272*e4b17023SJohn Marino shared_ptr&
273*e4b17023SJohn Marino operator=(const shared_ptr<_Tp1>& __r) noexcept
274*e4b17023SJohn Marino {
275*e4b17023SJohn Marino this->__shared_ptr<_Tp>::operator=(__r);
276*e4b17023SJohn Marino return *this;
277*e4b17023SJohn Marino }
278*e4b17023SJohn Marino
279*e4b17023SJohn Marino #if _GLIBCXX_USE_DEPRECATED
280*e4b17023SJohn Marino template<typename _Tp1>
281*e4b17023SJohn Marino shared_ptr&
282*e4b17023SJohn Marino operator=(std::auto_ptr<_Tp1>&& __r)
283*e4b17023SJohn Marino {
284*e4b17023SJohn Marino this->__shared_ptr<_Tp>::operator=(std::move(__r));
285*e4b17023SJohn Marino return *this;
286*e4b17023SJohn Marino }
287*e4b17023SJohn Marino #endif
288*e4b17023SJohn Marino
289*e4b17023SJohn Marino shared_ptr&
290*e4b17023SJohn Marino operator=(shared_ptr&& __r) noexcept
291*e4b17023SJohn Marino {
292*e4b17023SJohn Marino this->__shared_ptr<_Tp>::operator=(std::move(__r));
293*e4b17023SJohn Marino return *this;
294*e4b17023SJohn Marino }
295*e4b17023SJohn Marino
296*e4b17023SJohn Marino template<class _Tp1>
297*e4b17023SJohn Marino shared_ptr&
298*e4b17023SJohn Marino operator=(shared_ptr<_Tp1>&& __r) noexcept
299*e4b17023SJohn Marino {
300*e4b17023SJohn Marino this->__shared_ptr<_Tp>::operator=(std::move(__r));
301*e4b17023SJohn Marino return *this;
302*e4b17023SJohn Marino }
303*e4b17023SJohn Marino
304*e4b17023SJohn Marino template<typename _Tp1, typename _Del>
305*e4b17023SJohn Marino shared_ptr&
306*e4b17023SJohn Marino operator=(std::unique_ptr<_Tp1, _Del>&& __r)
307*e4b17023SJohn Marino {
308*e4b17023SJohn Marino this->__shared_ptr<_Tp>::operator=(std::move(__r));
309*e4b17023SJohn Marino return *this;
310*e4b17023SJohn Marino }
311*e4b17023SJohn Marino
312*e4b17023SJohn Marino private:
313*e4b17023SJohn Marino // This constructor is non-standard, it is used by allocate_shared.
314*e4b17023SJohn Marino template<typename _Alloc, typename... _Args>
315*e4b17023SJohn Marino shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
316*e4b17023SJohn Marino _Args&&... __args)
317*e4b17023SJohn Marino : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
318*e4b17023SJohn Marino { }
319*e4b17023SJohn Marino
320*e4b17023SJohn Marino template<typename _Tp1, typename _Alloc, typename... _Args>
321*e4b17023SJohn Marino friend shared_ptr<_Tp1>
322*e4b17023SJohn Marino allocate_shared(const _Alloc& __a, _Args&&... __args);
323*e4b17023SJohn Marino };
324*e4b17023SJohn Marino
325*e4b17023SJohn Marino // 20.8.13.2.7 shared_ptr comparisons
326*e4b17023SJohn Marino template<typename _Tp1, typename _Tp2>
327*e4b17023SJohn Marino inline bool
328*e4b17023SJohn Marino operator==(const shared_ptr<_Tp1>& __a,
329*e4b17023SJohn Marino const shared_ptr<_Tp2>& __b) noexcept
330*e4b17023SJohn Marino { return __a.get() == __b.get(); }
331*e4b17023SJohn Marino
332*e4b17023SJohn Marino template<typename _Tp>
333*e4b17023SJohn Marino inline bool
334*e4b17023SJohn Marino operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
335*e4b17023SJohn Marino { return !__a; }
336*e4b17023SJohn Marino
337*e4b17023SJohn Marino template<typename _Tp>
338*e4b17023SJohn Marino inline bool
339*e4b17023SJohn Marino operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
340*e4b17023SJohn Marino { return !__a; }
341*e4b17023SJohn Marino
342*e4b17023SJohn Marino template<typename _Tp1, typename _Tp2>
343*e4b17023SJohn Marino inline bool
344*e4b17023SJohn Marino operator!=(const shared_ptr<_Tp1>& __a,
345*e4b17023SJohn Marino const shared_ptr<_Tp2>& __b) noexcept
346*e4b17023SJohn Marino { return __a.get() != __b.get(); }
347*e4b17023SJohn Marino
348*e4b17023SJohn Marino template<typename _Tp>
349*e4b17023SJohn Marino inline bool
350*e4b17023SJohn Marino operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
351*e4b17023SJohn Marino { return (bool)__a; }
352*e4b17023SJohn Marino
353*e4b17023SJohn Marino template<typename _Tp>
354*e4b17023SJohn Marino inline bool
355*e4b17023SJohn Marino operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
356*e4b17023SJohn Marino { return (bool)__a; }
357*e4b17023SJohn Marino
358*e4b17023SJohn Marino template<typename _Tp1, typename _Tp2>
359*e4b17023SJohn Marino inline bool
360*e4b17023SJohn Marino operator<(const shared_ptr<_Tp1>& __a,
361*e4b17023SJohn Marino const shared_ptr<_Tp2>& __b) noexcept
362*e4b17023SJohn Marino {
363*e4b17023SJohn Marino typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
364*e4b17023SJohn Marino return std::less<_CT>()(__a.get(), __b.get());
365*e4b17023SJohn Marino }
366*e4b17023SJohn Marino
367*e4b17023SJohn Marino template<typename _Tp>
368*e4b17023SJohn Marino inline bool
369*e4b17023SJohn Marino operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
370*e4b17023SJohn Marino { return std::less<_Tp*>()(__a.get(), nullptr); }
371*e4b17023SJohn Marino
372*e4b17023SJohn Marino template<typename _Tp>
373*e4b17023SJohn Marino inline bool
374*e4b17023SJohn Marino operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
375*e4b17023SJohn Marino { return std::less<_Tp*>()(nullptr, __a.get()); }
376*e4b17023SJohn Marino
377*e4b17023SJohn Marino template<typename _Tp1, typename _Tp2>
378*e4b17023SJohn Marino inline bool
379*e4b17023SJohn Marino operator<=(const shared_ptr<_Tp1>& __a,
380*e4b17023SJohn Marino const shared_ptr<_Tp2>& __b) noexcept
381*e4b17023SJohn Marino { return !(__b < __a); }
382*e4b17023SJohn Marino
383*e4b17023SJohn Marino template<typename _Tp>
384*e4b17023SJohn Marino inline bool
385*e4b17023SJohn Marino operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
386*e4b17023SJohn Marino { return !(nullptr < __a); }
387*e4b17023SJohn Marino
388*e4b17023SJohn Marino template<typename _Tp>
389*e4b17023SJohn Marino inline bool
390*e4b17023SJohn Marino operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
391*e4b17023SJohn Marino { return !(__a < nullptr); }
392*e4b17023SJohn Marino
393*e4b17023SJohn Marino template<typename _Tp1, typename _Tp2>
394*e4b17023SJohn Marino inline bool
395*e4b17023SJohn Marino operator>(const shared_ptr<_Tp1>& __a,
396*e4b17023SJohn Marino const shared_ptr<_Tp2>& __b) noexcept
397*e4b17023SJohn Marino { return (__b < __a); }
398*e4b17023SJohn Marino
399*e4b17023SJohn Marino template<typename _Tp>
400*e4b17023SJohn Marino inline bool
401*e4b17023SJohn Marino operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
402*e4b17023SJohn Marino { return std::less<_Tp*>()(nullptr, __a.get()); }
403*e4b17023SJohn Marino
404*e4b17023SJohn Marino template<typename _Tp>
405*e4b17023SJohn Marino inline bool
406*e4b17023SJohn Marino operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
407*e4b17023SJohn Marino { return std::less<_Tp*>()(__a.get(), nullptr); }
408*e4b17023SJohn Marino
409*e4b17023SJohn Marino template<typename _Tp1, typename _Tp2>
410*e4b17023SJohn Marino inline bool
411*e4b17023SJohn Marino operator>=(const shared_ptr<_Tp1>& __a,
412*e4b17023SJohn Marino const shared_ptr<_Tp2>& __b) noexcept
413*e4b17023SJohn Marino { return !(__a < __b); }
414*e4b17023SJohn Marino
415*e4b17023SJohn Marino template<typename _Tp>
416*e4b17023SJohn Marino inline bool
417*e4b17023SJohn Marino operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
418*e4b17023SJohn Marino { return !(__a < nullptr); }
419*e4b17023SJohn Marino
420*e4b17023SJohn Marino template<typename _Tp>
421*e4b17023SJohn Marino inline bool
422*e4b17023SJohn Marino operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
423*e4b17023SJohn Marino { return !(nullptr < __a); }
424*e4b17023SJohn Marino
425*e4b17023SJohn Marino template<typename _Tp>
426*e4b17023SJohn Marino struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>>
427*e4b17023SJohn Marino { };
428*e4b17023SJohn Marino
429*e4b17023SJohn Marino // 20.8.13.2.9 shared_ptr specialized algorithms.
430*e4b17023SJohn Marino template<typename _Tp>
431*e4b17023SJohn Marino inline void
432*e4b17023SJohn Marino swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
433*e4b17023SJohn Marino { __a.swap(__b); }
434*e4b17023SJohn Marino
435*e4b17023SJohn Marino // 20.8.13.2.10 shared_ptr casts.
436*e4b17023SJohn Marino template<typename _Tp, typename _Tp1>
437*e4b17023SJohn Marino inline shared_ptr<_Tp>
438*e4b17023SJohn Marino static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
439*e4b17023SJohn Marino { return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); }
440*e4b17023SJohn Marino
441*e4b17023SJohn Marino template<typename _Tp, typename _Tp1>
442*e4b17023SJohn Marino inline shared_ptr<_Tp>
443*e4b17023SJohn Marino const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
444*e4b17023SJohn Marino { return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); }
445*e4b17023SJohn Marino
446*e4b17023SJohn Marino template<typename _Tp, typename _Tp1>
447*e4b17023SJohn Marino inline shared_ptr<_Tp>
448*e4b17023SJohn Marino dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
449*e4b17023SJohn Marino {
450*e4b17023SJohn Marino if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
451*e4b17023SJohn Marino return shared_ptr<_Tp>(__r, __p);
452*e4b17023SJohn Marino return shared_ptr<_Tp>();
453*e4b17023SJohn Marino }
454*e4b17023SJohn Marino
455*e4b17023SJohn Marino
456*e4b17023SJohn Marino /**
457*e4b17023SJohn Marino * @brief A smart pointer with weak semantics.
458*e4b17023SJohn Marino *
459*e4b17023SJohn Marino * With forwarding constructors and assignment operators.
460*e4b17023SJohn Marino */
461*e4b17023SJohn Marino template<typename _Tp>
462*e4b17023SJohn Marino class weak_ptr : public __weak_ptr<_Tp>
463*e4b17023SJohn Marino {
464*e4b17023SJohn Marino public:
465*e4b17023SJohn Marino constexpr weak_ptr() noexcept
466*e4b17023SJohn Marino : __weak_ptr<_Tp>() { }
467*e4b17023SJohn Marino
468*e4b17023SJohn Marino template<typename _Tp1, typename = typename
469*e4b17023SJohn Marino std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
470*e4b17023SJohn Marino weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
471*e4b17023SJohn Marino : __weak_ptr<_Tp>(__r) { }
472*e4b17023SJohn Marino
473*e4b17023SJohn Marino template<typename _Tp1, typename = typename
474*e4b17023SJohn Marino std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
475*e4b17023SJohn Marino weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
476*e4b17023SJohn Marino : __weak_ptr<_Tp>(__r) { }
477*e4b17023SJohn Marino
478*e4b17023SJohn Marino template<typename _Tp1>
479*e4b17023SJohn Marino weak_ptr&
480*e4b17023SJohn Marino operator=(const weak_ptr<_Tp1>& __r) noexcept
481*e4b17023SJohn Marino {
482*e4b17023SJohn Marino this->__weak_ptr<_Tp>::operator=(__r);
483*e4b17023SJohn Marino return *this;
484*e4b17023SJohn Marino }
485*e4b17023SJohn Marino
486*e4b17023SJohn Marino template<typename _Tp1>
487*e4b17023SJohn Marino weak_ptr&
488*e4b17023SJohn Marino operator=(const shared_ptr<_Tp1>& __r) noexcept
489*e4b17023SJohn Marino {
490*e4b17023SJohn Marino this->__weak_ptr<_Tp>::operator=(__r);
491*e4b17023SJohn Marino return *this;
492*e4b17023SJohn Marino }
493*e4b17023SJohn Marino
494*e4b17023SJohn Marino shared_ptr<_Tp>
495*e4b17023SJohn Marino lock() const noexcept
496*e4b17023SJohn Marino {
497*e4b17023SJohn Marino #ifdef __GTHREADS
498*e4b17023SJohn Marino if (this->expired())
499*e4b17023SJohn Marino return shared_ptr<_Tp>();
500*e4b17023SJohn Marino
501*e4b17023SJohn Marino __try
502*e4b17023SJohn Marino {
503*e4b17023SJohn Marino return shared_ptr<_Tp>(*this);
504*e4b17023SJohn Marino }
505*e4b17023SJohn Marino __catch(const bad_weak_ptr&)
506*e4b17023SJohn Marino {
507*e4b17023SJohn Marino return shared_ptr<_Tp>();
508*e4b17023SJohn Marino }
509*e4b17023SJohn Marino #else
510*e4b17023SJohn Marino return this->expired() ? shared_ptr<_Tp>() : shared_ptr<_Tp>(*this);
511*e4b17023SJohn Marino #endif
512*e4b17023SJohn Marino }
513*e4b17023SJohn Marino };
514*e4b17023SJohn Marino
515*e4b17023SJohn Marino // 20.8.13.3.7 weak_ptr specialized algorithms.
516*e4b17023SJohn Marino template<typename _Tp>
517*e4b17023SJohn Marino inline void
518*e4b17023SJohn Marino swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
519*e4b17023SJohn Marino { __a.swap(__b); }
520*e4b17023SJohn Marino
521*e4b17023SJohn Marino
522*e4b17023SJohn Marino /// Primary template owner_less
523*e4b17023SJohn Marino template<typename _Tp>
524*e4b17023SJohn Marino struct owner_less;
525*e4b17023SJohn Marino
526*e4b17023SJohn Marino /// Partial specialization of owner_less for shared_ptr.
527*e4b17023SJohn Marino template<typename _Tp>
528*e4b17023SJohn Marino struct owner_less<shared_ptr<_Tp>>
529*e4b17023SJohn Marino : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
530*e4b17023SJohn Marino { };
531*e4b17023SJohn Marino
532*e4b17023SJohn Marino /// Partial specialization of owner_less for weak_ptr.
533*e4b17023SJohn Marino template<typename _Tp>
534*e4b17023SJohn Marino struct owner_less<weak_ptr<_Tp>>
535*e4b17023SJohn Marino : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
536*e4b17023SJohn Marino { };
537*e4b17023SJohn Marino
538*e4b17023SJohn Marino /**
539*e4b17023SJohn Marino * @brief Base class allowing use of member function shared_from_this.
540*e4b17023SJohn Marino */
541*e4b17023SJohn Marino template<typename _Tp>
542*e4b17023SJohn Marino class enable_shared_from_this
543*e4b17023SJohn Marino {
544*e4b17023SJohn Marino protected:
545*e4b17023SJohn Marino constexpr enable_shared_from_this() noexcept { }
546*e4b17023SJohn Marino
547*e4b17023SJohn Marino enable_shared_from_this(const enable_shared_from_this&) noexcept { }
548*e4b17023SJohn Marino
549*e4b17023SJohn Marino enable_shared_from_this&
550*e4b17023SJohn Marino operator=(const enable_shared_from_this&) noexcept
551*e4b17023SJohn Marino { return *this; }
552*e4b17023SJohn Marino
553*e4b17023SJohn Marino ~enable_shared_from_this() { }
554*e4b17023SJohn Marino
555*e4b17023SJohn Marino public:
556*e4b17023SJohn Marino shared_ptr<_Tp>
557*e4b17023SJohn Marino shared_from_this()
558*e4b17023SJohn Marino { return shared_ptr<_Tp>(this->_M_weak_this); }
559*e4b17023SJohn Marino
560*e4b17023SJohn Marino shared_ptr<const _Tp>
561*e4b17023SJohn Marino shared_from_this() const
562*e4b17023SJohn Marino { return shared_ptr<const _Tp>(this->_M_weak_this); }
563*e4b17023SJohn Marino
564*e4b17023SJohn Marino private:
565*e4b17023SJohn Marino template<typename _Tp1>
566*e4b17023SJohn Marino void
567*e4b17023SJohn Marino _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
568*e4b17023SJohn Marino { _M_weak_this._M_assign(__p, __n); }
569*e4b17023SJohn Marino
570*e4b17023SJohn Marino template<typename _Tp1>
571*e4b17023SJohn Marino friend void
572*e4b17023SJohn Marino __enable_shared_from_this_helper(const __shared_count<>& __pn,
573*e4b17023SJohn Marino const enable_shared_from_this* __pe,
574*e4b17023SJohn Marino const _Tp1* __px) noexcept
575*e4b17023SJohn Marino {
576*e4b17023SJohn Marino if (__pe != 0)
577*e4b17023SJohn Marino __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
578*e4b17023SJohn Marino }
579*e4b17023SJohn Marino
580*e4b17023SJohn Marino mutable weak_ptr<_Tp> _M_weak_this;
581*e4b17023SJohn Marino };
582*e4b17023SJohn Marino
583*e4b17023SJohn Marino /**
584*e4b17023SJohn Marino * @brief Create an object that is owned by a shared_ptr.
585*e4b17023SJohn Marino * @param __a An allocator.
586*e4b17023SJohn Marino * @param __args Arguments for the @a _Tp object's constructor.
587*e4b17023SJohn Marino * @return A shared_ptr that owns the newly created object.
588*e4b17023SJohn Marino * @throw An exception thrown from @a _Alloc::allocate or from the
589*e4b17023SJohn Marino * constructor of @a _Tp.
590*e4b17023SJohn Marino *
591*e4b17023SJohn Marino * A copy of @a __a will be used to allocate memory for the shared_ptr
592*e4b17023SJohn Marino * and the new object.
593*e4b17023SJohn Marino */
594*e4b17023SJohn Marino template<typename _Tp, typename _Alloc, typename... _Args>
595*e4b17023SJohn Marino inline shared_ptr<_Tp>
596*e4b17023SJohn Marino allocate_shared(const _Alloc& __a, _Args&&... __args)
597*e4b17023SJohn Marino {
598*e4b17023SJohn Marino return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a,
599*e4b17023SJohn Marino std::forward<_Args>(__args)...);
600*e4b17023SJohn Marino }
601*e4b17023SJohn Marino
602*e4b17023SJohn Marino /**
603*e4b17023SJohn Marino * @brief Create an object that is owned by a shared_ptr.
604*e4b17023SJohn Marino * @param __args Arguments for the @a _Tp object's constructor.
605*e4b17023SJohn Marino * @return A shared_ptr that owns the newly created object.
606*e4b17023SJohn Marino * @throw std::bad_alloc, or an exception thrown from the
607*e4b17023SJohn Marino * constructor of @a _Tp.
608*e4b17023SJohn Marino */
609*e4b17023SJohn Marino template<typename _Tp, typename... _Args>
610*e4b17023SJohn Marino inline shared_ptr<_Tp>
611*e4b17023SJohn Marino make_shared(_Args&&... __args)
612*e4b17023SJohn Marino {
613*e4b17023SJohn Marino typedef typename std::remove_const<_Tp>::type _Tp_nc;
614*e4b17023SJohn Marino return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
615*e4b17023SJohn Marino std::forward<_Args>(__args)...);
616*e4b17023SJohn Marino }
617*e4b17023SJohn Marino
618*e4b17023SJohn Marino /// std::hash specialization for shared_ptr.
619*e4b17023SJohn Marino template<typename _Tp>
620*e4b17023SJohn Marino struct hash<shared_ptr<_Tp>>
621*e4b17023SJohn Marino : public __hash_base<size_t, shared_ptr<_Tp>>
622*e4b17023SJohn Marino {
623*e4b17023SJohn Marino size_t
624*e4b17023SJohn Marino operator()(const shared_ptr<_Tp>& __s) const noexcept
625*e4b17023SJohn Marino { return std::hash<_Tp*>()(__s.get()); }
626*e4b17023SJohn Marino };
627*e4b17023SJohn Marino
628*e4b17023SJohn Marino // @} group pointer_abstractions
629*e4b17023SJohn Marino
630*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
631*e4b17023SJohn Marino } // namespace
632*e4b17023SJohn Marino
633*e4b17023SJohn Marino #endif // _SHARED_PTR_H
634