1*38fd1498Szrj // Experimental shared_ptr with array support -*- C++ -*-
2*38fd1498Szrj
3*38fd1498Szrj // Copyright (C) 2015-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 /** @file experimental/bits/shared_ptr.h
26*38fd1498Szrj * This is an internal header file, included by other library headers.
27*38fd1498Szrj * Do not attempt to use it directly. @headername{experimental/memory}
28*38fd1498Szrj */
29*38fd1498Szrj
30*38fd1498Szrj #ifndef _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H
31*38fd1498Szrj #define _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 1
32*38fd1498Szrj
33*38fd1498Szrj #pragma GCC system_header
34*38fd1498Szrj
35*38fd1498Szrj #if __cplusplus >= 201402L
36*38fd1498Szrj
37*38fd1498Szrj #include <memory>
38*38fd1498Szrj #include <experimental/type_traits>
39*38fd1498Szrj
_GLIBCXX_VISIBILITY(default)40*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
41*38fd1498Szrj {
42*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
43*38fd1498Szrj
44*38fd1498Szrj namespace experimental
45*38fd1498Szrj {
46*38fd1498Szrj inline namespace fundamentals_v2
47*38fd1498Szrj {
48*38fd1498Szrj // 8.2.1
49*38fd1498Szrj
50*38fd1498Szrj template<typename _Tp> class shared_ptr;
51*38fd1498Szrj template<typename _Tp> class weak_ptr;
52*38fd1498Szrj template<typename _Tp> class enable_shared_from_this;
53*38fd1498Szrj
54*38fd1498Szrj template<typename _Yp, typename _Tp>
55*38fd1498Szrj constexpr bool __sp_compatible_v
56*38fd1498Szrj = std::__sp_compatible_with<_Yp*, _Tp*>::value;
57*38fd1498Szrj
58*38fd1498Szrj template<typename _Tp, typename _Yp>
59*38fd1498Szrj constexpr bool __sp_is_constructible_v
60*38fd1498Szrj = std::__sp_is_constructible<_Tp, _Yp>::value;
61*38fd1498Szrj
62*38fd1498Szrj template<typename _Tp>
63*38fd1498Szrj class shared_ptr : public __shared_ptr<_Tp>
64*38fd1498Szrj {
65*38fd1498Szrj using _Base_type = __shared_ptr<_Tp>;
66*38fd1498Szrj
67*38fd1498Szrj public:
68*38fd1498Szrj using element_type = typename _Base_type::element_type;
69*38fd1498Szrj
70*38fd1498Szrj private:
71*38fd1498Szrj // Constraint for construction from a pointer of type _Yp*:
72*38fd1498Szrj template<typename _Yp>
73*38fd1498Szrj using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
74*38fd1498Szrj
75*38fd1498Szrj template<typename _Tp1, typename _Res = void>
76*38fd1498Szrj using _Compatible
77*38fd1498Szrj = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
78*38fd1498Szrj
79*38fd1498Szrj template<typename _Tp1, typename _Del,
80*38fd1498Szrj typename _Ptr = typename unique_ptr<_Tp1, _Del>::pointer,
81*38fd1498Szrj typename _Res = void>
82*38fd1498Szrj using _UniqCompatible = enable_if_t<
83*38fd1498Szrj __sp_compatible_v<_Tp1, _Tp>
84*38fd1498Szrj && experimental::is_convertible_v<_Ptr, element_type*>,
85*38fd1498Szrj _Res>;
86*38fd1498Szrj
87*38fd1498Szrj public:
88*38fd1498Szrj
89*38fd1498Szrj // 8.2.1.1, shared_ptr constructors
90*38fd1498Szrj constexpr shared_ptr() noexcept = default;
91*38fd1498Szrj
92*38fd1498Szrj template<typename _Tp1, typename = _SafeConv<_Tp1>>
93*38fd1498Szrj explicit
94*38fd1498Szrj shared_ptr(_Tp1* __p) : _Base_type(__p)
95*38fd1498Szrj { _M_enable_shared_from_this_with(__p); }
96*38fd1498Szrj
97*38fd1498Szrj template<typename _Tp1, typename _Deleter, typename = _SafeConv<_Tp1>>
98*38fd1498Szrj shared_ptr(_Tp1* __p, _Deleter __d)
99*38fd1498Szrj : _Base_type(__p, __d)
100*38fd1498Szrj { _M_enable_shared_from_this_with(__p); }
101*38fd1498Szrj
102*38fd1498Szrj template<typename _Tp1, typename _Deleter, typename _Alloc,
103*38fd1498Szrj typename = _SafeConv<_Tp1>>
104*38fd1498Szrj shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
105*38fd1498Szrj : _Base_type(__p, __d, __a)
106*38fd1498Szrj { _M_enable_shared_from_this_with(__p); }
107*38fd1498Szrj
108*38fd1498Szrj template<typename _Deleter>
109*38fd1498Szrj shared_ptr(nullptr_t __p, _Deleter __d)
110*38fd1498Szrj : _Base_type(__p, __d) { }
111*38fd1498Szrj
112*38fd1498Szrj template<typename _Deleter, typename _Alloc>
113*38fd1498Szrj shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
114*38fd1498Szrj : _Base_type(__p, __d, __a) { }
115*38fd1498Szrj
116*38fd1498Szrj template<typename _Tp1>
117*38fd1498Szrj shared_ptr(const shared_ptr<_Tp1>& __r, element_type* __p) noexcept
118*38fd1498Szrj : _Base_type(__r, __p) { }
119*38fd1498Szrj
120*38fd1498Szrj shared_ptr(const shared_ptr& __r) noexcept
121*38fd1498Szrj : _Base_type(__r) { }
122*38fd1498Szrj
123*38fd1498Szrj template<typename _Tp1, typename = _Compatible<_Tp1>>
124*38fd1498Szrj shared_ptr(const shared_ptr<_Tp1>& __r) noexcept
125*38fd1498Szrj : _Base_type(__r) { }
126*38fd1498Szrj
127*38fd1498Szrj shared_ptr(shared_ptr&& __r) noexcept
128*38fd1498Szrj : _Base_type(std::move(__r)) { }
129*38fd1498Szrj
130*38fd1498Szrj template<typename _Tp1, typename = _Compatible<_Tp1>>
131*38fd1498Szrj shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
132*38fd1498Szrj : _Base_type(std::move(__r)) { }
133*38fd1498Szrj
134*38fd1498Szrj template<typename _Tp1, typename = _Compatible<_Tp1>>
135*38fd1498Szrj explicit
136*38fd1498Szrj shared_ptr(const weak_ptr<_Tp1>& __r)
137*38fd1498Szrj : _Base_type(__r) { }
138*38fd1498Szrj
139*38fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
140*38fd1498Szrj template<typename _Tp1, typename = _Compatible<_Tp1>>
141*38fd1498Szrj shared_ptr(std::auto_ptr<_Tp1>&& __r)
142*38fd1498Szrj : _Base_type(std::move(__r))
143*38fd1498Szrj { _M_enable_shared_from_this_with(static_cast<_Tp1*>(this->get())); }
144*38fd1498Szrj #endif
145*38fd1498Szrj
146*38fd1498Szrj template<typename _Tp1, typename _Del,
147*38fd1498Szrj typename = _UniqCompatible<_Tp1, _Del>>
148*38fd1498Szrj shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
149*38fd1498Szrj : _Base_type(std::move(__r))
150*38fd1498Szrj {
151*38fd1498Szrj // XXX assume conversion from __r.get() to this->get() to __elem_t*
152*38fd1498Szrj // is a round trip, which might not be true in all cases.
153*38fd1498Szrj using __elem_t = typename unique_ptr<_Tp1, _Del>::element_type;
154*38fd1498Szrj _M_enable_shared_from_this_with(static_cast<__elem_t*>(this->get()));
155*38fd1498Szrj }
156*38fd1498Szrj
157*38fd1498Szrj constexpr shared_ptr(nullptr_t __p)
158*38fd1498Szrj : _Base_type(__p) { }
159*38fd1498Szrj
160*38fd1498Szrj // C++14 §20.8.2.2
161*38fd1498Szrj ~shared_ptr() = default;
162*38fd1498Szrj
163*38fd1498Szrj // C++14 §20.8.2.3
164*38fd1498Szrj shared_ptr& operator=(const shared_ptr&) noexcept = default;
165*38fd1498Szrj
166*38fd1498Szrj template <typename _Tp1>
167*38fd1498Szrj _Compatible<_Tp1, shared_ptr&>
168*38fd1498Szrj operator=(const shared_ptr<_Tp1>& __r) noexcept
169*38fd1498Szrj {
170*38fd1498Szrj _Base_type::operator=(__r);
171*38fd1498Szrj return *this;
172*38fd1498Szrj }
173*38fd1498Szrj
174*38fd1498Szrj shared_ptr&
175*38fd1498Szrj operator=(shared_ptr&& __r) noexcept
176*38fd1498Szrj {
177*38fd1498Szrj _Base_type::operator=(std::move(__r));
178*38fd1498Szrj return *this;
179*38fd1498Szrj }
180*38fd1498Szrj
181*38fd1498Szrj template <typename _Tp1>
182*38fd1498Szrj _Compatible<_Tp1, shared_ptr&>
183*38fd1498Szrj operator=(shared_ptr<_Tp1>&& __r) noexcept
184*38fd1498Szrj {
185*38fd1498Szrj _Base_type::operator=(std::move(__r));
186*38fd1498Szrj return *this;
187*38fd1498Szrj }
188*38fd1498Szrj
189*38fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
190*38fd1498Szrj template<typename _Tp1>
191*38fd1498Szrj _Compatible<_Tp1, shared_ptr&>
192*38fd1498Szrj operator=(std::auto_ptr<_Tp1>&& __r)
193*38fd1498Szrj {
194*38fd1498Szrj __shared_ptr<_Tp>::operator=(std::move(__r));
195*38fd1498Szrj return *this;
196*38fd1498Szrj }
197*38fd1498Szrj #endif
198*38fd1498Szrj
199*38fd1498Szrj template <typename _Tp1, typename _Del>
200*38fd1498Szrj _UniqCompatible<_Tp1, _Del, shared_ptr&>
201*38fd1498Szrj operator=(unique_ptr<_Tp1, _Del>&& __r)
202*38fd1498Szrj {
203*38fd1498Szrj _Base_type::operator=(std::move(__r));
204*38fd1498Szrj return *this;
205*38fd1498Szrj }
206*38fd1498Szrj
207*38fd1498Szrj // C++14 §20.8.2.2.4
208*38fd1498Szrj // swap & reset
209*38fd1498Szrj // 8.2.1.2 shared_ptr observers
210*38fd1498Szrj // in __shared_ptr
211*38fd1498Szrj
212*38fd1498Szrj private:
213*38fd1498Szrj template<typename _Alloc, typename... _Args>
214*38fd1498Szrj shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
215*38fd1498Szrj _Args&&... __args)
216*38fd1498Szrj : _Base_type(__tag, __a, std::forward<_Args>(__args)...)
217*38fd1498Szrj { _M_enable_shared_from_this_with(this->get()); }
218*38fd1498Szrj
219*38fd1498Szrj template<typename _Tp1, typename _Alloc, typename... _Args>
220*38fd1498Szrj friend shared_ptr<_Tp1>
221*38fd1498Szrj allocate_shared(const _Alloc& __a, _Args&&... __args);
222*38fd1498Szrj
223*38fd1498Szrj shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
224*38fd1498Szrj : _Base_type(__r, std::nothrow) { }
225*38fd1498Szrj
226*38fd1498Szrj friend class weak_ptr<_Tp>;
227*38fd1498Szrj
228*38fd1498Szrj template<typename _Yp>
229*38fd1498Szrj using __esft_base_t =
230*38fd1498Szrj decltype(__expt_enable_shared_from_this_base(std::declval<_Yp*>()));
231*38fd1498Szrj
232*38fd1498Szrj // Detect an accessible and unambiguous enable_shared_from_this base.
233*38fd1498Szrj template<typename _Yp, typename = void>
234*38fd1498Szrj struct __has_esft_base
235*38fd1498Szrj : false_type { };
236*38fd1498Szrj
237*38fd1498Szrj template<typename _Yp>
238*38fd1498Szrj struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
239*38fd1498Szrj : __bool_constant<!is_array_v<_Tp>> { }; // ignore base for arrays
240*38fd1498Szrj
241*38fd1498Szrj template<typename _Yp>
242*38fd1498Szrj typename enable_if<__has_esft_base<_Yp>::value>::type
243*38fd1498Szrj _M_enable_shared_from_this_with(const _Yp* __p) noexcept
244*38fd1498Szrj {
245*38fd1498Szrj if (auto __base = __expt_enable_shared_from_this_base(__p))
246*38fd1498Szrj {
247*38fd1498Szrj __base->_M_weak_this
248*38fd1498Szrj = shared_ptr<_Yp>(*this, const_cast<_Yp*>(__p));
249*38fd1498Szrj }
250*38fd1498Szrj }
251*38fd1498Szrj
252*38fd1498Szrj template<typename _Yp>
253*38fd1498Szrj typename enable_if<!__has_esft_base<_Yp>::value>::type
254*38fd1498Szrj _M_enable_shared_from_this_with(const _Yp*) noexcept
255*38fd1498Szrj { }
256*38fd1498Szrj };
257*38fd1498Szrj
258*38fd1498Szrj // C++14 §20.8.2.2.7 //DOING
259*38fd1498Szrj template<typename _Tp1, typename _Tp2>
260*38fd1498Szrj bool operator==(const shared_ptr<_Tp1>& __a,
261*38fd1498Szrj const shared_ptr<_Tp2>& __b) noexcept
262*38fd1498Szrj { return __a.get() == __b.get(); }
263*38fd1498Szrj
264*38fd1498Szrj template<typename _Tp>
265*38fd1498Szrj inline bool
266*38fd1498Szrj operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
267*38fd1498Szrj { return !__a; }
268*38fd1498Szrj
269*38fd1498Szrj template<typename _Tp>
270*38fd1498Szrj inline bool
271*38fd1498Szrj operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
272*38fd1498Szrj { return !__a; }
273*38fd1498Szrj
274*38fd1498Szrj template<typename _Tp1, typename _Tp2>
275*38fd1498Szrj inline bool
276*38fd1498Szrj operator!=(const shared_ptr<_Tp1>& __a,
277*38fd1498Szrj const shared_ptr<_Tp2>& __b) noexcept
278*38fd1498Szrj { return __a.get() != __b.get(); }
279*38fd1498Szrj
280*38fd1498Szrj template<typename _Tp>
281*38fd1498Szrj inline bool
282*38fd1498Szrj operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
283*38fd1498Szrj { return (bool)__a; }
284*38fd1498Szrj
285*38fd1498Szrj template<typename _Tp>
286*38fd1498Szrj inline bool
287*38fd1498Szrj operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
288*38fd1498Szrj { return (bool)__a; }
289*38fd1498Szrj
290*38fd1498Szrj template<typename _Tp1, typename _Tp2>
291*38fd1498Szrj inline bool
292*38fd1498Szrj operator<(const shared_ptr<_Tp1>& __a,
293*38fd1498Szrj const shared_ptr<_Tp2>& __b) noexcept
294*38fd1498Szrj {
295*38fd1498Szrj using __elem_t1 = typename shared_ptr<_Tp1>::element_type;
296*38fd1498Szrj using __elem_t2 = typename shared_ptr<_Tp2>::element_type;
297*38fd1498Szrj using _CT = common_type_t<__elem_t1*, __elem_t2*>;
298*38fd1498Szrj return std::less<_CT>()(__a.get(), __b.get());
299*38fd1498Szrj }
300*38fd1498Szrj
301*38fd1498Szrj template<typename _Tp>
302*38fd1498Szrj inline bool
303*38fd1498Szrj operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
304*38fd1498Szrj {
305*38fd1498Szrj using __elem_t = typename shared_ptr<_Tp>::element_type;
306*38fd1498Szrj return std::less<__elem_t*>()(__a.get(), nullptr);
307*38fd1498Szrj }
308*38fd1498Szrj
309*38fd1498Szrj template<typename _Tp>
310*38fd1498Szrj inline bool
311*38fd1498Szrj operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
312*38fd1498Szrj {
313*38fd1498Szrj using __elem_t = typename shared_ptr<_Tp>::element_type;
314*38fd1498Szrj return std::less<__elem_t*>()(nullptr, __a.get());
315*38fd1498Szrj }
316*38fd1498Szrj
317*38fd1498Szrj template<typename _Tp1, typename _Tp2>
318*38fd1498Szrj inline bool
319*38fd1498Szrj operator<=(const shared_ptr<_Tp1>& __a,
320*38fd1498Szrj const shared_ptr<_Tp2>& __b) noexcept
321*38fd1498Szrj { return !(__b < __a); }
322*38fd1498Szrj
323*38fd1498Szrj template<typename _Tp>
324*38fd1498Szrj inline bool
325*38fd1498Szrj operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
326*38fd1498Szrj { return !(nullptr < __a); }
327*38fd1498Szrj
328*38fd1498Szrj template<typename _Tp>
329*38fd1498Szrj inline bool
330*38fd1498Szrj operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
331*38fd1498Szrj { return !(__a < nullptr); }
332*38fd1498Szrj
333*38fd1498Szrj template<typename _Tp1, typename _Tp2>
334*38fd1498Szrj inline bool
335*38fd1498Szrj operator>(const shared_ptr<_Tp1>& __a,
336*38fd1498Szrj const shared_ptr<_Tp2>& __b) noexcept
337*38fd1498Szrj { return (__b < __a); }
338*38fd1498Szrj
339*38fd1498Szrj template<typename _Tp>
340*38fd1498Szrj inline bool
341*38fd1498Szrj operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
342*38fd1498Szrj {
343*38fd1498Szrj using __elem_t = typename shared_ptr<_Tp>::element_type;
344*38fd1498Szrj return std::less<__elem_t*>()(nullptr, __a.get());
345*38fd1498Szrj }
346*38fd1498Szrj
347*38fd1498Szrj template<typename _Tp>
348*38fd1498Szrj inline bool
349*38fd1498Szrj operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
350*38fd1498Szrj {
351*38fd1498Szrj using __elem_t = typename shared_ptr<_Tp>::element_type;
352*38fd1498Szrj return std::less<__elem_t*>()(__a.get(), nullptr);
353*38fd1498Szrj }
354*38fd1498Szrj
355*38fd1498Szrj template<typename _Tp1, typename _Tp2>
356*38fd1498Szrj inline bool
357*38fd1498Szrj operator>=(const shared_ptr<_Tp1>& __a,
358*38fd1498Szrj const shared_ptr<_Tp2>& __b) noexcept
359*38fd1498Szrj { return !(__a < __b); }
360*38fd1498Szrj
361*38fd1498Szrj template<typename _Tp>
362*38fd1498Szrj inline bool
363*38fd1498Szrj operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
364*38fd1498Szrj { return !(__a < nullptr); }
365*38fd1498Szrj
366*38fd1498Szrj template<typename _Tp>
367*38fd1498Szrj inline bool
368*38fd1498Szrj operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
369*38fd1498Szrj { return !(nullptr < __a); }
370*38fd1498Szrj
371*38fd1498Szrj // C++14 §20.8.2.2.8
372*38fd1498Szrj template<typename _Tp>
373*38fd1498Szrj inline void
374*38fd1498Szrj swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
375*38fd1498Szrj { __a.swap(__b); }
376*38fd1498Szrj
377*38fd1498Szrj // 8.2.1.3, shared_ptr casts
378*38fd1498Szrj template<typename _Tp, typename _Tp1>
379*38fd1498Szrj inline shared_ptr<_Tp>
380*38fd1498Szrj static_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
381*38fd1498Szrj {
382*38fd1498Szrj using __elem_t = typename shared_ptr<_Tp>::element_type;
383*38fd1498Szrj return shared_ptr<_Tp>(__r, static_cast<__elem_t*>(__r.get()));
384*38fd1498Szrj }
385*38fd1498Szrj
386*38fd1498Szrj template<typename _Tp, typename _Tp1>
387*38fd1498Szrj inline shared_ptr<_Tp>
388*38fd1498Szrj dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
389*38fd1498Szrj {
390*38fd1498Szrj using __elem_t = typename shared_ptr<_Tp>::element_type;
391*38fd1498Szrj if (_Tp* __p = dynamic_cast<__elem_t*>(__r.get()))
392*38fd1498Szrj return shared_ptr<_Tp>(__r, __p);
393*38fd1498Szrj return shared_ptr<_Tp>();
394*38fd1498Szrj }
395*38fd1498Szrj
396*38fd1498Szrj template<typename _Tp, typename _Tp1>
397*38fd1498Szrj inline shared_ptr<_Tp>
398*38fd1498Szrj const_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
399*38fd1498Szrj {
400*38fd1498Szrj using __elem_t = typename shared_ptr<_Tp>::element_type;
401*38fd1498Szrj return shared_ptr<_Tp>(__r, const_cast<__elem_t*>(__r.get()));
402*38fd1498Szrj }
403*38fd1498Szrj
404*38fd1498Szrj template<typename _Tp, typename _Tp1>
405*38fd1498Szrj inline shared_ptr<_Tp>
406*38fd1498Szrj reinterpret_pointer_cast(const shared_ptr<_Tp1>& __r) noexcept
407*38fd1498Szrj {
408*38fd1498Szrj using __elem_t = typename shared_ptr<_Tp>::element_type;
409*38fd1498Szrj return shared_ptr<_Tp>(__r, reinterpret_cast<__elem_t*>(__r.get()));
410*38fd1498Szrj }
411*38fd1498Szrj
412*38fd1498Szrj // C++14 §20.8.2.3
413*38fd1498Szrj template<typename _Tp>
414*38fd1498Szrj class weak_ptr : public __weak_ptr<_Tp>
415*38fd1498Szrj {
416*38fd1498Szrj template<typename _Tp1, typename _Res = void>
417*38fd1498Szrj using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
418*38fd1498Szrj
419*38fd1498Szrj using _Base_type = __weak_ptr<_Tp>;
420*38fd1498Szrj
421*38fd1498Szrj public:
422*38fd1498Szrj constexpr weak_ptr() noexcept = default;
423*38fd1498Szrj
424*38fd1498Szrj template<typename _Tp1, typename = _Compatible<_Tp1>>
425*38fd1498Szrj weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
426*38fd1498Szrj : _Base_type(__r) { }
427*38fd1498Szrj
428*38fd1498Szrj weak_ptr(const weak_ptr&) noexcept = default;
429*38fd1498Szrj
430*38fd1498Szrj template<typename _Tp1, typename = _Compatible<_Tp1>>
431*38fd1498Szrj weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
432*38fd1498Szrj : _Base_type(__r) { }
433*38fd1498Szrj
434*38fd1498Szrj weak_ptr(weak_ptr&&) noexcept = default;
435*38fd1498Szrj
436*38fd1498Szrj template<typename _Tp1, typename = _Compatible<_Tp1>>
437*38fd1498Szrj weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
438*38fd1498Szrj : _Base_type(std::move(__r)) { }
439*38fd1498Szrj
440*38fd1498Szrj weak_ptr&
441*38fd1498Szrj operator=(const weak_ptr& __r) noexcept = default;
442*38fd1498Szrj
443*38fd1498Szrj template<typename _Tp1>
444*38fd1498Szrj _Compatible<_Tp1, weak_ptr&>
445*38fd1498Szrj operator=(const weak_ptr<_Tp1>& __r) noexcept
446*38fd1498Szrj {
447*38fd1498Szrj this->_Base_type::operator=(__r);
448*38fd1498Szrj return *this;
449*38fd1498Szrj }
450*38fd1498Szrj
451*38fd1498Szrj template<typename _Tp1>
452*38fd1498Szrj _Compatible<_Tp1, weak_ptr&>
453*38fd1498Szrj operator=(const shared_ptr<_Tp1>& __r) noexcept
454*38fd1498Szrj {
455*38fd1498Szrj this->_Base_type::operator=(__r);
456*38fd1498Szrj return *this;
457*38fd1498Szrj }
458*38fd1498Szrj
459*38fd1498Szrj weak_ptr&
460*38fd1498Szrj operator=(weak_ptr&& __r) noexcept = default;
461*38fd1498Szrj
462*38fd1498Szrj template<typename _Tp1>
463*38fd1498Szrj _Compatible<_Tp1, weak_ptr&>
464*38fd1498Szrj operator=(weak_ptr<_Tp1>&& __r) noexcept
465*38fd1498Szrj {
466*38fd1498Szrj this->_Base_type::operator=(std::move(__r));
467*38fd1498Szrj return *this;
468*38fd1498Szrj }
469*38fd1498Szrj
470*38fd1498Szrj shared_ptr<_Tp>
471*38fd1498Szrj lock() const noexcept
472*38fd1498Szrj { return shared_ptr<_Tp>(*this, std::nothrow); }
473*38fd1498Szrj
474*38fd1498Szrj friend class enable_shared_from_this<_Tp>;
475*38fd1498Szrj };
476*38fd1498Szrj
477*38fd1498Szrj // C++14 §20.8.2.3.6
478*38fd1498Szrj template<typename _Tp>
479*38fd1498Szrj inline void
480*38fd1498Szrj swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
481*38fd1498Szrj { __a.swap(__b); }
482*38fd1498Szrj
483*38fd1498Szrj /// C++14 §20.8.2.2.10
484*38fd1498Szrj template<typename _Del, typename _Tp>
485*38fd1498Szrj inline _Del*
486*38fd1498Szrj get_deleter(const shared_ptr<_Tp>& __p) noexcept
487*38fd1498Szrj { return std::get_deleter<_Del>(__p); }
488*38fd1498Szrj
489*38fd1498Szrj // C++14 §20.8.2.2.11
490*38fd1498Szrj template<typename _Ch, typename _Tr, typename _Tp>
491*38fd1498Szrj inline std::basic_ostream<_Ch, _Tr>&
492*38fd1498Szrj operator<<(std::basic_ostream<_Ch, _Tr>& __os, const shared_ptr<_Tp>& __p)
493*38fd1498Szrj {
494*38fd1498Szrj __os << __p.get();
495*38fd1498Szrj return __os;
496*38fd1498Szrj }
497*38fd1498Szrj
498*38fd1498Szrj // C++14 §20.8.2.4
499*38fd1498Szrj template<typename _Tp = void> class owner_less;
500*38fd1498Szrj
501*38fd1498Szrj /// Partial specialization of owner_less for shared_ptr.
502*38fd1498Szrj template<typename _Tp>
503*38fd1498Szrj struct owner_less<shared_ptr<_Tp>>
504*38fd1498Szrj : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
505*38fd1498Szrj { };
506*38fd1498Szrj
507*38fd1498Szrj /// Partial specialization of owner_less for weak_ptr.
508*38fd1498Szrj template<typename _Tp>
509*38fd1498Szrj struct owner_less<weak_ptr<_Tp>>
510*38fd1498Szrj : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
511*38fd1498Szrj { };
512*38fd1498Szrj
513*38fd1498Szrj template<>
514*38fd1498Szrj class owner_less<void>
515*38fd1498Szrj {
516*38fd1498Szrj template<typename _Tp, typename _Up>
517*38fd1498Szrj bool
518*38fd1498Szrj operator()(shared_ptr<_Tp> const& __lhs,
519*38fd1498Szrj shared_ptr<_Up> const& __rhs) const
520*38fd1498Szrj { return __lhs.owner_before(__rhs); }
521*38fd1498Szrj
522*38fd1498Szrj template<typename _Tp, typename _Up>
523*38fd1498Szrj bool
524*38fd1498Szrj operator()(shared_ptr<_Tp> const& __lhs,
525*38fd1498Szrj weak_ptr<_Up> const& __rhs) const
526*38fd1498Szrj { return __lhs.owner_before(__rhs); }
527*38fd1498Szrj
528*38fd1498Szrj template<typename _Tp, typename _Up>
529*38fd1498Szrj bool
530*38fd1498Szrj operator()(weak_ptr<_Tp> const& __lhs,
531*38fd1498Szrj shared_ptr<_Up> const& __rhs) const
532*38fd1498Szrj { return __lhs.owner_before(__rhs); }
533*38fd1498Szrj
534*38fd1498Szrj template<typename _Tp, typename _Up>
535*38fd1498Szrj bool
536*38fd1498Szrj operator()(weak_ptr<_Tp> const& __lhs,
537*38fd1498Szrj weak_ptr<_Up> const& __rhs) const
538*38fd1498Szrj { return __lhs.owner_before(__rhs); }
539*38fd1498Szrj
540*38fd1498Szrj typedef void is_transparent;
541*38fd1498Szrj };
542*38fd1498Szrj
543*38fd1498Szrj // C++14 §20.8.2.6
544*38fd1498Szrj template<typename _Tp>
545*38fd1498Szrj inline bool
546*38fd1498Szrj atomic_is_lock_free(const shared_ptr<_Tp>* __p)
547*38fd1498Szrj { return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }
548*38fd1498Szrj
549*38fd1498Szrj template<typename _Tp>
550*38fd1498Szrj shared_ptr<_Tp> atomic_load(const shared_ptr<_Tp>* __p)
551*38fd1498Szrj { return std::atomic_load<_Tp>(__p); }
552*38fd1498Szrj
553*38fd1498Szrj template<typename _Tp>
554*38fd1498Szrj shared_ptr<_Tp>
555*38fd1498Szrj atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order __mo)
556*38fd1498Szrj { return std::atomic_load_explicit<_Tp>(__p, __mo); }
557*38fd1498Szrj
558*38fd1498Szrj template<typename _Tp>
559*38fd1498Szrj void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
560*38fd1498Szrj { return std::atomic_store<_Tp>(__p, __r); }
561*38fd1498Szrj
562*38fd1498Szrj template<typename _Tp>
563*38fd1498Szrj shared_ptr<_Tp>
564*38fd1498Szrj atomic_store_explicit(const shared_ptr<_Tp>* __p,
565*38fd1498Szrj shared_ptr<_Tp> __r,
566*38fd1498Szrj memory_order __mo)
567*38fd1498Szrj { return std::atomic_store_explicit<_Tp>(__p, __r, __mo); }
568*38fd1498Szrj
569*38fd1498Szrj template<typename _Tp>
570*38fd1498Szrj void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
571*38fd1498Szrj { return std::atomic_exchange<_Tp>(__p, __r); }
572*38fd1498Szrj
573*38fd1498Szrj template<typename _Tp>
574*38fd1498Szrj shared_ptr<_Tp>
575*38fd1498Szrj atomic_exchange_explicit(const shared_ptr<_Tp>* __p,
576*38fd1498Szrj shared_ptr<_Tp> __r,
577*38fd1498Szrj memory_order __mo)
578*38fd1498Szrj { return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); }
579*38fd1498Szrj
580*38fd1498Szrj template<typename _Tp>
581*38fd1498Szrj bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p,
582*38fd1498Szrj shared_ptr<_Tp>* __v,
583*38fd1498Szrj shared_ptr<_Tp> __w)
584*38fd1498Szrj { return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); }
585*38fd1498Szrj
586*38fd1498Szrj template<typename _Tp>
587*38fd1498Szrj bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p,
588*38fd1498Szrj shared_ptr<_Tp>* __v,
589*38fd1498Szrj shared_ptr<_Tp> __w)
590*38fd1498Szrj { return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); }
591*38fd1498Szrj
592*38fd1498Szrj template<typename _Tp>
593*38fd1498Szrj bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
594*38fd1498Szrj shared_ptr<_Tp>* __v,
595*38fd1498Szrj shared_ptr<_Tp> __w,
596*38fd1498Szrj memory_order __success,
597*38fd1498Szrj memory_order __failure)
598*38fd1498Szrj { return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w,
599*38fd1498Szrj __success,
600*38fd1498Szrj __failure); }
601*38fd1498Szrj
602*38fd1498Szrj template<typename _Tp>
603*38fd1498Szrj bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
604*38fd1498Szrj shared_ptr<_Tp>* __v,
605*38fd1498Szrj shared_ptr<_Tp> __w,
606*38fd1498Szrj memory_order __success,
607*38fd1498Szrj memory_order __failure)
608*38fd1498Szrj { return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w,
609*38fd1498Szrj __success,
610*38fd1498Szrj __failure); }
611*38fd1498Szrj
612*38fd1498Szrj //enable_shared_from_this
613*38fd1498Szrj template<typename _Tp>
614*38fd1498Szrj class enable_shared_from_this
615*38fd1498Szrj {
616*38fd1498Szrj protected:
617*38fd1498Szrj constexpr enable_shared_from_this() noexcept { }
618*38fd1498Szrj
619*38fd1498Szrj enable_shared_from_this(const enable_shared_from_this&) noexcept { }
620*38fd1498Szrj
621*38fd1498Szrj enable_shared_from_this&
622*38fd1498Szrj operator=(const enable_shared_from_this&) noexcept
623*38fd1498Szrj { return *this; }
624*38fd1498Szrj
625*38fd1498Szrj ~enable_shared_from_this() { }
626*38fd1498Szrj
627*38fd1498Szrj public:
628*38fd1498Szrj shared_ptr<_Tp>
629*38fd1498Szrj shared_from_this()
630*38fd1498Szrj { return shared_ptr<_Tp>(this->_M_weak_this); }
631*38fd1498Szrj
632*38fd1498Szrj shared_ptr<const _Tp>
633*38fd1498Szrj shared_from_this() const
634*38fd1498Szrj { return shared_ptr<const _Tp>(this->_M_weak_this); }
635*38fd1498Szrj
636*38fd1498Szrj weak_ptr<_Tp>
637*38fd1498Szrj weak_from_this() noexcept
638*38fd1498Szrj { return _M_weak_this; }
639*38fd1498Szrj
640*38fd1498Szrj weak_ptr<const _Tp>
641*38fd1498Szrj weak_from_this() const noexcept
642*38fd1498Szrj { return _M_weak_this; }
643*38fd1498Szrj
644*38fd1498Szrj private:
645*38fd1498Szrj template<typename _Tp1>
646*38fd1498Szrj void
647*38fd1498Szrj _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
648*38fd1498Szrj { _M_weak_this._M_assign(__p, __n); }
649*38fd1498Szrj
650*38fd1498Szrj // Found by ADL when this is an associated class.
651*38fd1498Szrj friend const enable_shared_from_this*
652*38fd1498Szrj __expt_enable_shared_from_this_base(const enable_shared_from_this* __p)
653*38fd1498Szrj { return __p; }
654*38fd1498Szrj
655*38fd1498Szrj template<typename>
656*38fd1498Szrj friend class shared_ptr;
657*38fd1498Szrj
658*38fd1498Szrj mutable weak_ptr<_Tp> _M_weak_this;
659*38fd1498Szrj };
660*38fd1498Szrj } // namespace fundamentals_v2
661*38fd1498Szrj } // namespace experimental
662*38fd1498Szrj
663*38fd1498Szrj /// std::hash specialization for shared_ptr.
664*38fd1498Szrj template<typename _Tp>
665*38fd1498Szrj struct hash<experimental::shared_ptr<_Tp>>
666*38fd1498Szrj : public __hash_base<size_t, experimental::shared_ptr<_Tp>>
667*38fd1498Szrj {
668*38fd1498Szrj size_t
669*38fd1498Szrj operator()(const experimental::shared_ptr<_Tp>& __s) const noexcept
670*38fd1498Szrj { return std::hash<_Tp*>()(__s.get()); }
671*38fd1498Szrj };
672*38fd1498Szrj
673*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
674*38fd1498Szrj } // namespace std
675*38fd1498Szrj
676*38fd1498Szrj #endif // __cplusplus <= 201103L
677*38fd1498Szrj
678*38fd1498Szrj #endif // _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H
679