1*38fd1498Szrj // <tr1/shared_ptr.h> -*- 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 // shared_count.hpp
26*38fd1498Szrj // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
27*38fd1498Szrj
28*38fd1498Szrj // shared_ptr.hpp
29*38fd1498Szrj // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
30*38fd1498Szrj // Copyright (C) 2001, 2002, 2003 Peter Dimov
31*38fd1498Szrj
32*38fd1498Szrj // weak_ptr.hpp
33*38fd1498Szrj // Copyright (C) 2001, 2002, 2003 Peter Dimov
34*38fd1498Szrj
35*38fd1498Szrj // enable_shared_from_this.hpp
36*38fd1498Szrj // Copyright (C) 2002 Peter Dimov
37*38fd1498Szrj
38*38fd1498Szrj // Distributed under the Boost Software License, Version 1.0. (See
39*38fd1498Szrj // accompanying file LICENSE_1_0.txt or copy at
40*38fd1498Szrj // http://www.boost.org/LICENSE_1_0.txt)
41*38fd1498Szrj
42*38fd1498Szrj // GCC Note: based on version 1.32.0 of the Boost library.
43*38fd1498Szrj
44*38fd1498Szrj /** @file tr1/shared_ptr.h
45*38fd1498Szrj * This is an internal header file, included by other library headers.
46*38fd1498Szrj * Do not attempt to use it directly. @headername{tr1/memory}
47*38fd1498Szrj */
48*38fd1498Szrj
49*38fd1498Szrj #ifndef _TR1_SHARED_PTR_H
50*38fd1498Szrj #define _TR1_SHARED_PTR_H 1
51*38fd1498Szrj
_GLIBCXX_VISIBILITY(default)52*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
53*38fd1498Szrj {
54*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
55*38fd1498Szrj
56*38fd1498Szrj namespace tr1
57*38fd1498Szrj {
58*38fd1498Szrj /**
59*38fd1498Szrj * @brief Exception possibly thrown by @c shared_ptr.
60*38fd1498Szrj * @ingroup exceptions
61*38fd1498Szrj */
62*38fd1498Szrj class bad_weak_ptr : public std::exception
63*38fd1498Szrj {
64*38fd1498Szrj public:
65*38fd1498Szrj virtual char const*
66*38fd1498Szrj what() const throw()
67*38fd1498Szrj { return "tr1::bad_weak_ptr"; }
68*38fd1498Szrj };
69*38fd1498Szrj
70*38fd1498Szrj // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
71*38fd1498Szrj inline void
72*38fd1498Szrj __throw_bad_weak_ptr()
73*38fd1498Szrj { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
74*38fd1498Szrj
75*38fd1498Szrj using __gnu_cxx::_Lock_policy;
76*38fd1498Szrj using __gnu_cxx::__default_lock_policy;
77*38fd1498Szrj using __gnu_cxx::_S_single;
78*38fd1498Szrj using __gnu_cxx::_S_mutex;
79*38fd1498Szrj using __gnu_cxx::_S_atomic;
80*38fd1498Szrj
81*38fd1498Szrj // Empty helper class except when the template argument is _S_mutex.
82*38fd1498Szrj template<_Lock_policy _Lp>
83*38fd1498Szrj class _Mutex_base
84*38fd1498Szrj {
85*38fd1498Szrj protected:
86*38fd1498Szrj // The atomic policy uses fully-fenced builtins, single doesn't care.
87*38fd1498Szrj enum { _S_need_barriers = 0 };
88*38fd1498Szrj };
89*38fd1498Szrj
90*38fd1498Szrj template<>
91*38fd1498Szrj class _Mutex_base<_S_mutex>
92*38fd1498Szrj : public __gnu_cxx::__mutex
93*38fd1498Szrj {
94*38fd1498Szrj protected:
95*38fd1498Szrj // This policy is used when atomic builtins are not available.
96*38fd1498Szrj // The replacement atomic operations might not have the necessary
97*38fd1498Szrj // memory barriers.
98*38fd1498Szrj enum { _S_need_barriers = 1 };
99*38fd1498Szrj };
100*38fd1498Szrj
101*38fd1498Szrj template<_Lock_policy _Lp = __default_lock_policy>
102*38fd1498Szrj class _Sp_counted_base
103*38fd1498Szrj : public _Mutex_base<_Lp>
104*38fd1498Szrj {
105*38fd1498Szrj public:
106*38fd1498Szrj _Sp_counted_base()
107*38fd1498Szrj : _M_use_count(1), _M_weak_count(1) { }
108*38fd1498Szrj
109*38fd1498Szrj virtual
110*38fd1498Szrj ~_Sp_counted_base() // nothrow
111*38fd1498Szrj { }
112*38fd1498Szrj
113*38fd1498Szrj // Called when _M_use_count drops to zero, to release the resources
114*38fd1498Szrj // managed by *this.
115*38fd1498Szrj virtual void
116*38fd1498Szrj _M_dispose() = 0; // nothrow
117*38fd1498Szrj
118*38fd1498Szrj // Called when _M_weak_count drops to zero.
119*38fd1498Szrj virtual void
120*38fd1498Szrj _M_destroy() // nothrow
121*38fd1498Szrj { delete this; }
122*38fd1498Szrj
123*38fd1498Szrj virtual void*
124*38fd1498Szrj _M_get_deleter(const std::type_info&) = 0;
125*38fd1498Szrj
126*38fd1498Szrj void
127*38fd1498Szrj _M_add_ref_copy()
128*38fd1498Szrj { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
129*38fd1498Szrj
130*38fd1498Szrj void
131*38fd1498Szrj _M_add_ref_lock();
132*38fd1498Szrj
133*38fd1498Szrj void
134*38fd1498Szrj _M_release() // nothrow
135*38fd1498Szrj {
136*38fd1498Szrj // Be race-detector-friendly. For more info see bits/c++config.
137*38fd1498Szrj _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
138*38fd1498Szrj if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
139*38fd1498Szrj {
140*38fd1498Szrj _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
141*38fd1498Szrj _M_dispose();
142*38fd1498Szrj // There must be a memory barrier between dispose() and destroy()
143*38fd1498Szrj // to ensure that the effects of dispose() are observed in the
144*38fd1498Szrj // thread that runs destroy().
145*38fd1498Szrj // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
146*38fd1498Szrj if (_Mutex_base<_Lp>::_S_need_barriers)
147*38fd1498Szrj {
148*38fd1498Szrj __atomic_thread_fence (__ATOMIC_ACQ_REL);
149*38fd1498Szrj }
150*38fd1498Szrj
151*38fd1498Szrj // Be race-detector-friendly. For more info see bits/c++config.
152*38fd1498Szrj _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
153*38fd1498Szrj if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
154*38fd1498Szrj -1) == 1)
155*38fd1498Szrj {
156*38fd1498Szrj _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
157*38fd1498Szrj _M_destroy();
158*38fd1498Szrj }
159*38fd1498Szrj }
160*38fd1498Szrj }
161*38fd1498Szrj
162*38fd1498Szrj void
163*38fd1498Szrj _M_weak_add_ref() // nothrow
164*38fd1498Szrj { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
165*38fd1498Szrj
166*38fd1498Szrj void
167*38fd1498Szrj _M_weak_release() // nothrow
168*38fd1498Szrj {
169*38fd1498Szrj // Be race-detector-friendly. For more info see bits/c++config.
170*38fd1498Szrj _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
171*38fd1498Szrj if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
172*38fd1498Szrj {
173*38fd1498Szrj _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
174*38fd1498Szrj if (_Mutex_base<_Lp>::_S_need_barriers)
175*38fd1498Szrj {
176*38fd1498Szrj // See _M_release(),
177*38fd1498Szrj // destroy() must observe results of dispose()
178*38fd1498Szrj __atomic_thread_fence (__ATOMIC_ACQ_REL);
179*38fd1498Szrj }
180*38fd1498Szrj _M_destroy();
181*38fd1498Szrj }
182*38fd1498Szrj }
183*38fd1498Szrj
184*38fd1498Szrj long
185*38fd1498Szrj _M_get_use_count() const // nothrow
186*38fd1498Szrj {
187*38fd1498Szrj // No memory barrier is used here so there is no synchronization
188*38fd1498Szrj // with other threads.
189*38fd1498Szrj return const_cast<const volatile _Atomic_word&>(_M_use_count);
190*38fd1498Szrj }
191*38fd1498Szrj
192*38fd1498Szrj private:
193*38fd1498Szrj _Sp_counted_base(_Sp_counted_base const&);
194*38fd1498Szrj _Sp_counted_base& operator=(_Sp_counted_base const&);
195*38fd1498Szrj
196*38fd1498Szrj _Atomic_word _M_use_count; // #shared
197*38fd1498Szrj _Atomic_word _M_weak_count; // #weak + (#shared != 0)
198*38fd1498Szrj };
199*38fd1498Szrj
200*38fd1498Szrj template<>
201*38fd1498Szrj inline void
202*38fd1498Szrj _Sp_counted_base<_S_single>::
203*38fd1498Szrj _M_add_ref_lock()
204*38fd1498Szrj {
205*38fd1498Szrj if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
206*38fd1498Szrj {
207*38fd1498Szrj _M_use_count = 0;
208*38fd1498Szrj __throw_bad_weak_ptr();
209*38fd1498Szrj }
210*38fd1498Szrj }
211*38fd1498Szrj
212*38fd1498Szrj template<>
213*38fd1498Szrj inline void
214*38fd1498Szrj _Sp_counted_base<_S_mutex>::
215*38fd1498Szrj _M_add_ref_lock()
216*38fd1498Szrj {
217*38fd1498Szrj __gnu_cxx::__scoped_lock sentry(*this);
218*38fd1498Szrj if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
219*38fd1498Szrj {
220*38fd1498Szrj _M_use_count = 0;
221*38fd1498Szrj __throw_bad_weak_ptr();
222*38fd1498Szrj }
223*38fd1498Szrj }
224*38fd1498Szrj
225*38fd1498Szrj template<>
226*38fd1498Szrj inline void
227*38fd1498Szrj _Sp_counted_base<_S_atomic>::
228*38fd1498Szrj _M_add_ref_lock()
229*38fd1498Szrj {
230*38fd1498Szrj // Perform lock-free add-if-not-zero operation.
231*38fd1498Szrj _Atomic_word __count = _M_use_count;
232*38fd1498Szrj do
233*38fd1498Szrj {
234*38fd1498Szrj if (__count == 0)
235*38fd1498Szrj __throw_bad_weak_ptr();
236*38fd1498Szrj // Replace the current counter value with the old value + 1, as
237*38fd1498Szrj // long as it's not changed meanwhile.
238*38fd1498Szrj }
239*38fd1498Szrj while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
240*38fd1498Szrj true, __ATOMIC_ACQ_REL,
241*38fd1498Szrj __ATOMIC_RELAXED));
242*38fd1498Szrj }
243*38fd1498Szrj
244*38fd1498Szrj template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
245*38fd1498Szrj class _Sp_counted_base_impl
246*38fd1498Szrj : public _Sp_counted_base<_Lp>
247*38fd1498Szrj {
248*38fd1498Szrj public:
249*38fd1498Szrj // Precondition: __d(__p) must not throw.
250*38fd1498Szrj _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
251*38fd1498Szrj : _M_ptr(__p), _M_del(__d) { }
252*38fd1498Szrj
253*38fd1498Szrj virtual void
254*38fd1498Szrj _M_dispose() // nothrow
255*38fd1498Szrj { _M_del(_M_ptr); }
256*38fd1498Szrj
257*38fd1498Szrj virtual void*
258*38fd1498Szrj _M_get_deleter(const std::type_info& __ti)
259*38fd1498Szrj {
260*38fd1498Szrj #if __cpp_rtti
261*38fd1498Szrj return __ti == typeid(_Deleter) ? &_M_del : 0;
262*38fd1498Szrj #else
263*38fd1498Szrj return 0;
264*38fd1498Szrj #endif
265*38fd1498Szrj }
266*38fd1498Szrj
267*38fd1498Szrj private:
268*38fd1498Szrj _Sp_counted_base_impl(const _Sp_counted_base_impl&);
269*38fd1498Szrj _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
270*38fd1498Szrj
271*38fd1498Szrj _Ptr _M_ptr; // copy constructor must not throw
272*38fd1498Szrj _Deleter _M_del; // copy constructor must not throw
273*38fd1498Szrj };
274*38fd1498Szrj
275*38fd1498Szrj template<_Lock_policy _Lp = __default_lock_policy>
276*38fd1498Szrj class __weak_count;
277*38fd1498Szrj
278*38fd1498Szrj template<typename _Tp>
279*38fd1498Szrj struct _Sp_deleter
280*38fd1498Szrj {
281*38fd1498Szrj typedef void result_type;
282*38fd1498Szrj typedef _Tp* argument_type;
283*38fd1498Szrj void operator()(_Tp* __p) const { delete __p; }
284*38fd1498Szrj };
285*38fd1498Szrj
286*38fd1498Szrj template<_Lock_policy _Lp = __default_lock_policy>
287*38fd1498Szrj class __shared_count
288*38fd1498Szrj {
289*38fd1498Szrj public:
290*38fd1498Szrj __shared_count()
291*38fd1498Szrj : _M_pi(0) // nothrow
292*38fd1498Szrj { }
293*38fd1498Szrj
294*38fd1498Szrj template<typename _Ptr>
295*38fd1498Szrj __shared_count(_Ptr __p) : _M_pi(0)
296*38fd1498Szrj {
297*38fd1498Szrj __try
298*38fd1498Szrj {
299*38fd1498Szrj typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
300*38fd1498Szrj _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
301*38fd1498Szrj __p, _Sp_deleter<_Tp>());
302*38fd1498Szrj }
303*38fd1498Szrj __catch(...)
304*38fd1498Szrj {
305*38fd1498Szrj delete __p;
306*38fd1498Szrj __throw_exception_again;
307*38fd1498Szrj }
308*38fd1498Szrj }
309*38fd1498Szrj
310*38fd1498Szrj template<typename _Ptr, typename _Deleter>
311*38fd1498Szrj __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
312*38fd1498Szrj {
313*38fd1498Szrj __try
314*38fd1498Szrj {
315*38fd1498Szrj _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
316*38fd1498Szrj }
317*38fd1498Szrj __catch(...)
318*38fd1498Szrj {
319*38fd1498Szrj __d(__p); // Call _Deleter on __p.
320*38fd1498Szrj __throw_exception_again;
321*38fd1498Szrj }
322*38fd1498Szrj }
323*38fd1498Szrj
324*38fd1498Szrj // Special case for auto_ptr<_Tp> to provide the strong guarantee.
325*38fd1498Szrj template<typename _Tp>
326*38fd1498Szrj explicit
327*38fd1498Szrj __shared_count(std::auto_ptr<_Tp>& __r)
328*38fd1498Szrj : _M_pi(new _Sp_counted_base_impl<_Tp*,
329*38fd1498Szrj _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
330*38fd1498Szrj { __r.release(); }
331*38fd1498Szrj
332*38fd1498Szrj // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
333*38fd1498Szrj explicit
334*38fd1498Szrj __shared_count(const __weak_count<_Lp>& __r);
335*38fd1498Szrj
336*38fd1498Szrj ~__shared_count() // nothrow
337*38fd1498Szrj {
338*38fd1498Szrj if (_M_pi != 0)
339*38fd1498Szrj _M_pi->_M_release();
340*38fd1498Szrj }
341*38fd1498Szrj
342*38fd1498Szrj __shared_count(const __shared_count& __r)
343*38fd1498Szrj : _M_pi(__r._M_pi) // nothrow
344*38fd1498Szrj {
345*38fd1498Szrj if (_M_pi != 0)
346*38fd1498Szrj _M_pi->_M_add_ref_copy();
347*38fd1498Szrj }
348*38fd1498Szrj
349*38fd1498Szrj __shared_count&
350*38fd1498Szrj operator=(const __shared_count& __r) // nothrow
351*38fd1498Szrj {
352*38fd1498Szrj _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
353*38fd1498Szrj if (__tmp != _M_pi)
354*38fd1498Szrj {
355*38fd1498Szrj if (__tmp != 0)
356*38fd1498Szrj __tmp->_M_add_ref_copy();
357*38fd1498Szrj if (_M_pi != 0)
358*38fd1498Szrj _M_pi->_M_release();
359*38fd1498Szrj _M_pi = __tmp;
360*38fd1498Szrj }
361*38fd1498Szrj return *this;
362*38fd1498Szrj }
363*38fd1498Szrj
364*38fd1498Szrj void
365*38fd1498Szrj _M_swap(__shared_count& __r) // nothrow
366*38fd1498Szrj {
367*38fd1498Szrj _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
368*38fd1498Szrj __r._M_pi = _M_pi;
369*38fd1498Szrj _M_pi = __tmp;
370*38fd1498Szrj }
371*38fd1498Szrj
372*38fd1498Szrj long
373*38fd1498Szrj _M_get_use_count() const // nothrow
374*38fd1498Szrj { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
375*38fd1498Szrj
376*38fd1498Szrj bool
377*38fd1498Szrj _M_unique() const // nothrow
378*38fd1498Szrj { return this->_M_get_use_count() == 1; }
379*38fd1498Szrj
380*38fd1498Szrj friend inline bool
381*38fd1498Szrj operator==(const __shared_count& __a, const __shared_count& __b)
382*38fd1498Szrj { return __a._M_pi == __b._M_pi; }
383*38fd1498Szrj
384*38fd1498Szrj friend inline bool
385*38fd1498Szrj operator<(const __shared_count& __a, const __shared_count& __b)
386*38fd1498Szrj { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
387*38fd1498Szrj
388*38fd1498Szrj void*
389*38fd1498Szrj _M_get_deleter(const std::type_info& __ti) const
390*38fd1498Szrj { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
391*38fd1498Szrj
392*38fd1498Szrj private:
393*38fd1498Szrj friend class __weak_count<_Lp>;
394*38fd1498Szrj
395*38fd1498Szrj _Sp_counted_base<_Lp>* _M_pi;
396*38fd1498Szrj };
397*38fd1498Szrj
398*38fd1498Szrj
399*38fd1498Szrj template<_Lock_policy _Lp>
400*38fd1498Szrj class __weak_count
401*38fd1498Szrj {
402*38fd1498Szrj public:
403*38fd1498Szrj __weak_count()
404*38fd1498Szrj : _M_pi(0) // nothrow
405*38fd1498Szrj { }
406*38fd1498Szrj
407*38fd1498Szrj __weak_count(const __shared_count<_Lp>& __r)
408*38fd1498Szrj : _M_pi(__r._M_pi) // nothrow
409*38fd1498Szrj {
410*38fd1498Szrj if (_M_pi != 0)
411*38fd1498Szrj _M_pi->_M_weak_add_ref();
412*38fd1498Szrj }
413*38fd1498Szrj
414*38fd1498Szrj __weak_count(const __weak_count<_Lp>& __r)
415*38fd1498Szrj : _M_pi(__r._M_pi) // nothrow
416*38fd1498Szrj {
417*38fd1498Szrj if (_M_pi != 0)
418*38fd1498Szrj _M_pi->_M_weak_add_ref();
419*38fd1498Szrj }
420*38fd1498Szrj
421*38fd1498Szrj ~__weak_count() // nothrow
422*38fd1498Szrj {
423*38fd1498Szrj if (_M_pi != 0)
424*38fd1498Szrj _M_pi->_M_weak_release();
425*38fd1498Szrj }
426*38fd1498Szrj
427*38fd1498Szrj __weak_count<_Lp>&
428*38fd1498Szrj operator=(const __shared_count<_Lp>& __r) // nothrow
429*38fd1498Szrj {
430*38fd1498Szrj _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
431*38fd1498Szrj if (__tmp != 0)
432*38fd1498Szrj __tmp->_M_weak_add_ref();
433*38fd1498Szrj if (_M_pi != 0)
434*38fd1498Szrj _M_pi->_M_weak_release();
435*38fd1498Szrj _M_pi = __tmp;
436*38fd1498Szrj return *this;
437*38fd1498Szrj }
438*38fd1498Szrj
439*38fd1498Szrj __weak_count<_Lp>&
440*38fd1498Szrj operator=(const __weak_count<_Lp>& __r) // nothrow
441*38fd1498Szrj {
442*38fd1498Szrj _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
443*38fd1498Szrj if (__tmp != 0)
444*38fd1498Szrj __tmp->_M_weak_add_ref();
445*38fd1498Szrj if (_M_pi != 0)
446*38fd1498Szrj _M_pi->_M_weak_release();
447*38fd1498Szrj _M_pi = __tmp;
448*38fd1498Szrj return *this;
449*38fd1498Szrj }
450*38fd1498Szrj
451*38fd1498Szrj void
452*38fd1498Szrj _M_swap(__weak_count<_Lp>& __r) // nothrow
453*38fd1498Szrj {
454*38fd1498Szrj _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
455*38fd1498Szrj __r._M_pi = _M_pi;
456*38fd1498Szrj _M_pi = __tmp;
457*38fd1498Szrj }
458*38fd1498Szrj
459*38fd1498Szrj long
460*38fd1498Szrj _M_get_use_count() const // nothrow
461*38fd1498Szrj { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
462*38fd1498Szrj
463*38fd1498Szrj friend inline bool
464*38fd1498Szrj operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
465*38fd1498Szrj { return __a._M_pi == __b._M_pi; }
466*38fd1498Szrj
467*38fd1498Szrj friend inline bool
468*38fd1498Szrj operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
469*38fd1498Szrj { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
470*38fd1498Szrj
471*38fd1498Szrj private:
472*38fd1498Szrj friend class __shared_count<_Lp>;
473*38fd1498Szrj
474*38fd1498Szrj _Sp_counted_base<_Lp>* _M_pi;
475*38fd1498Szrj };
476*38fd1498Szrj
477*38fd1498Szrj // now that __weak_count is defined we can define this constructor:
478*38fd1498Szrj template<_Lock_policy _Lp>
479*38fd1498Szrj inline
480*38fd1498Szrj __shared_count<_Lp>::
481*38fd1498Szrj __shared_count(const __weak_count<_Lp>& __r)
482*38fd1498Szrj : _M_pi(__r._M_pi)
483*38fd1498Szrj {
484*38fd1498Szrj if (_M_pi != 0)
485*38fd1498Szrj _M_pi->_M_add_ref_lock();
486*38fd1498Szrj else
487*38fd1498Szrj __throw_bad_weak_ptr();
488*38fd1498Szrj }
489*38fd1498Szrj
490*38fd1498Szrj // Forward declarations.
491*38fd1498Szrj template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
492*38fd1498Szrj class __shared_ptr;
493*38fd1498Szrj
494*38fd1498Szrj template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
495*38fd1498Szrj class __weak_ptr;
496*38fd1498Szrj
497*38fd1498Szrj template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
498*38fd1498Szrj class __enable_shared_from_this;
499*38fd1498Szrj
500*38fd1498Szrj template<typename _Tp>
501*38fd1498Szrj class shared_ptr;
502*38fd1498Szrj
503*38fd1498Szrj template<typename _Tp>
504*38fd1498Szrj class weak_ptr;
505*38fd1498Szrj
506*38fd1498Szrj template<typename _Tp>
507*38fd1498Szrj class enable_shared_from_this;
508*38fd1498Szrj
509*38fd1498Szrj // Support for enable_shared_from_this.
510*38fd1498Szrj
511*38fd1498Szrj // Friend of __enable_shared_from_this.
512*38fd1498Szrj template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
513*38fd1498Szrj void
514*38fd1498Szrj __enable_shared_from_this_helper(const __shared_count<_Lp>&,
515*38fd1498Szrj const __enable_shared_from_this<_Tp1,
516*38fd1498Szrj _Lp>*, const _Tp2*);
517*38fd1498Szrj
518*38fd1498Szrj // Friend of enable_shared_from_this.
519*38fd1498Szrj template<typename _Tp1, typename _Tp2>
520*38fd1498Szrj void
521*38fd1498Szrj __enable_shared_from_this_helper(const __shared_count<>&,
522*38fd1498Szrj const enable_shared_from_this<_Tp1>*,
523*38fd1498Szrj const _Tp2*);
524*38fd1498Szrj
525*38fd1498Szrj template<_Lock_policy _Lp>
526*38fd1498Szrj inline void
527*38fd1498Szrj __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
528*38fd1498Szrj { }
529*38fd1498Szrj
530*38fd1498Szrj
531*38fd1498Szrj struct __static_cast_tag { };
532*38fd1498Szrj struct __const_cast_tag { };
533*38fd1498Szrj struct __dynamic_cast_tag { };
534*38fd1498Szrj
535*38fd1498Szrj // A smart pointer with reference-counted copy semantics. The
536*38fd1498Szrj // object pointed to is deleted when the last shared_ptr pointing to
537*38fd1498Szrj // it is destroyed or reset.
538*38fd1498Szrj template<typename _Tp, _Lock_policy _Lp>
539*38fd1498Szrj class __shared_ptr
540*38fd1498Szrj {
541*38fd1498Szrj public:
542*38fd1498Szrj typedef _Tp element_type;
543*38fd1498Szrj
544*38fd1498Szrj __shared_ptr()
545*38fd1498Szrj : _M_ptr(0), _M_refcount() // never throws
546*38fd1498Szrj { }
547*38fd1498Szrj
548*38fd1498Szrj template<typename _Tp1>
549*38fd1498Szrj explicit
550*38fd1498Szrj __shared_ptr(_Tp1* __p)
551*38fd1498Szrj : _M_ptr(__p), _M_refcount(__p)
552*38fd1498Szrj {
553*38fd1498Szrj __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
554*38fd1498Szrj typedef int _IsComplete[sizeof(_Tp1)];
555*38fd1498Szrj __enable_shared_from_this_helper(_M_refcount, __p, __p);
556*38fd1498Szrj }
557*38fd1498Szrj
558*38fd1498Szrj template<typename _Tp1, typename _Deleter>
559*38fd1498Szrj __shared_ptr(_Tp1* __p, _Deleter __d)
560*38fd1498Szrj : _M_ptr(__p), _M_refcount(__p, __d)
561*38fd1498Szrj {
562*38fd1498Szrj __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
563*38fd1498Szrj // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
564*38fd1498Szrj __enable_shared_from_this_helper(_M_refcount, __p, __p);
565*38fd1498Szrj }
566*38fd1498Szrj
567*38fd1498Szrj // generated copy constructor, assignment, destructor are fine.
568*38fd1498Szrj
569*38fd1498Szrj template<typename _Tp1>
570*38fd1498Szrj __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
571*38fd1498Szrj : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
572*38fd1498Szrj { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
573*38fd1498Szrj
574*38fd1498Szrj template<typename _Tp1>
575*38fd1498Szrj explicit
576*38fd1498Szrj __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
577*38fd1498Szrj : _M_refcount(__r._M_refcount) // may throw
578*38fd1498Szrj {
579*38fd1498Szrj __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
580*38fd1498Szrj // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
581*38fd1498Szrj // did not throw.
582*38fd1498Szrj _M_ptr = __r._M_ptr;
583*38fd1498Szrj }
584*38fd1498Szrj
585*38fd1498Szrj #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
586*38fd1498Szrj // Postcondition: use_count() == 1 and __r.get() == 0
587*38fd1498Szrj template<typename _Tp1>
588*38fd1498Szrj explicit
589*38fd1498Szrj __shared_ptr(std::auto_ptr<_Tp1>& __r)
590*38fd1498Szrj : _M_ptr(__r.get()), _M_refcount()
591*38fd1498Szrj { // TODO requries delete __r.release() well-formed
592*38fd1498Szrj __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
593*38fd1498Szrj typedef int _IsComplete[sizeof(_Tp1)];
594*38fd1498Szrj _Tp1* __tmp = __r.get();
595*38fd1498Szrj _M_refcount = __shared_count<_Lp>(__r);
596*38fd1498Szrj __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
597*38fd1498Szrj }
598*38fd1498Szrj
599*38fd1498Szrj #endif
600*38fd1498Szrj
601*38fd1498Szrj template<typename _Tp1>
602*38fd1498Szrj __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
603*38fd1498Szrj : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
604*38fd1498Szrj _M_refcount(__r._M_refcount)
605*38fd1498Szrj { }
606*38fd1498Szrj
607*38fd1498Szrj template<typename _Tp1>
608*38fd1498Szrj __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
609*38fd1498Szrj : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
610*38fd1498Szrj _M_refcount(__r._M_refcount)
611*38fd1498Szrj { }
612*38fd1498Szrj
613*38fd1498Szrj template<typename _Tp1>
614*38fd1498Szrj __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
615*38fd1498Szrj : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
616*38fd1498Szrj _M_refcount(__r._M_refcount)
617*38fd1498Szrj {
618*38fd1498Szrj if (_M_ptr == 0) // need to allocate new counter -- the cast failed
619*38fd1498Szrj _M_refcount = __shared_count<_Lp>();
620*38fd1498Szrj }
621*38fd1498Szrj
622*38fd1498Szrj template<typename _Tp1>
623*38fd1498Szrj __shared_ptr&
624*38fd1498Szrj operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
625*38fd1498Szrj {
626*38fd1498Szrj _M_ptr = __r._M_ptr;
627*38fd1498Szrj _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
628*38fd1498Szrj return *this;
629*38fd1498Szrj }
630*38fd1498Szrj
631*38fd1498Szrj #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
632*38fd1498Szrj template<typename _Tp1>
633*38fd1498Szrj __shared_ptr&
634*38fd1498Szrj operator=(std::auto_ptr<_Tp1>& __r)
635*38fd1498Szrj {
636*38fd1498Szrj __shared_ptr(__r).swap(*this);
637*38fd1498Szrj return *this;
638*38fd1498Szrj }
639*38fd1498Szrj #endif
640*38fd1498Szrj
641*38fd1498Szrj void
642*38fd1498Szrj reset() // never throws
643*38fd1498Szrj { __shared_ptr().swap(*this); }
644*38fd1498Szrj
645*38fd1498Szrj template<typename _Tp1>
646*38fd1498Szrj void
647*38fd1498Szrj reset(_Tp1* __p) // _Tp1 must be complete.
648*38fd1498Szrj {
649*38fd1498Szrj // Catch self-reset errors.
650*38fd1498Szrj _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
651*38fd1498Szrj __shared_ptr(__p).swap(*this);
652*38fd1498Szrj }
653*38fd1498Szrj
654*38fd1498Szrj template<typename _Tp1, typename _Deleter>
655*38fd1498Szrj void
656*38fd1498Szrj reset(_Tp1* __p, _Deleter __d)
657*38fd1498Szrj { __shared_ptr(__p, __d).swap(*this); }
658*38fd1498Szrj
659*38fd1498Szrj // Allow class instantiation when _Tp is [cv-qual] void.
660*38fd1498Szrj typename std::tr1::add_reference<_Tp>::type
661*38fd1498Szrj operator*() const // never throws
662*38fd1498Szrj {
663*38fd1498Szrj _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
664*38fd1498Szrj return *_M_ptr;
665*38fd1498Szrj }
666*38fd1498Szrj
667*38fd1498Szrj _Tp*
668*38fd1498Szrj operator->() const // never throws
669*38fd1498Szrj {
670*38fd1498Szrj _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
671*38fd1498Szrj return _M_ptr;
672*38fd1498Szrj }
673*38fd1498Szrj
674*38fd1498Szrj _Tp*
675*38fd1498Szrj get() const // never throws
676*38fd1498Szrj { return _M_ptr; }
677*38fd1498Szrj
678*38fd1498Szrj // Implicit conversion to "bool"
679*38fd1498Szrj private:
680*38fd1498Szrj typedef _Tp* __shared_ptr::*__unspecified_bool_type;
681*38fd1498Szrj
682*38fd1498Szrj public:
683*38fd1498Szrj operator __unspecified_bool_type() const // never throws
684*38fd1498Szrj { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
685*38fd1498Szrj
686*38fd1498Szrj bool
687*38fd1498Szrj unique() const // never throws
688*38fd1498Szrj { return _M_refcount._M_unique(); }
689*38fd1498Szrj
690*38fd1498Szrj long
691*38fd1498Szrj use_count() const // never throws
692*38fd1498Szrj { return _M_refcount._M_get_use_count(); }
693*38fd1498Szrj
694*38fd1498Szrj void
695*38fd1498Szrj swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
696*38fd1498Szrj {
697*38fd1498Szrj std::swap(_M_ptr, __other._M_ptr);
698*38fd1498Szrj _M_refcount._M_swap(__other._M_refcount);
699*38fd1498Szrj }
700*38fd1498Szrj
701*38fd1498Szrj private:
702*38fd1498Szrj void*
703*38fd1498Szrj _M_get_deleter(const std::type_info& __ti) const
704*38fd1498Szrj { return _M_refcount._M_get_deleter(__ti); }
705*38fd1498Szrj
706*38fd1498Szrj template<typename _Tp1, _Lock_policy _Lp1>
707*38fd1498Szrj bool
708*38fd1498Szrj _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
709*38fd1498Szrj { return _M_refcount < __rhs._M_refcount; }
710*38fd1498Szrj
711*38fd1498Szrj template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
712*38fd1498Szrj template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
713*38fd1498Szrj
714*38fd1498Szrj template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
715*38fd1498Szrj friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
716*38fd1498Szrj
717*38fd1498Szrj // Friends injected into enclosing namespace and found by ADL:
718*38fd1498Szrj template<typename _Tp1>
719*38fd1498Szrj friend inline bool
720*38fd1498Szrj operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
721*38fd1498Szrj { return __a.get() == __b.get(); }
722*38fd1498Szrj
723*38fd1498Szrj template<typename _Tp1>
724*38fd1498Szrj friend inline bool
725*38fd1498Szrj operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
726*38fd1498Szrj { return __a.get() != __b.get(); }
727*38fd1498Szrj
728*38fd1498Szrj template<typename _Tp1>
729*38fd1498Szrj friend inline bool
730*38fd1498Szrj operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
731*38fd1498Szrj { return __a._M_less(__b); }
732*38fd1498Szrj
733*38fd1498Szrj _Tp* _M_ptr; // Contained pointer.
734*38fd1498Szrj __shared_count<_Lp> _M_refcount; // Reference counter.
735*38fd1498Szrj };
736*38fd1498Szrj
737*38fd1498Szrj // 2.2.3.8 shared_ptr specialized algorithms.
738*38fd1498Szrj template<typename _Tp, _Lock_policy _Lp>
739*38fd1498Szrj inline void
740*38fd1498Szrj swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
741*38fd1498Szrj { __a.swap(__b); }
742*38fd1498Szrj
743*38fd1498Szrj // 2.2.3.9 shared_ptr casts
744*38fd1498Szrj /* The seemingly equivalent
745*38fd1498Szrj * shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
746*38fd1498Szrj * will eventually result in undefined behaviour,
747*38fd1498Szrj * attempting to delete the same object twice.
748*38fd1498Szrj */
749*38fd1498Szrj template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
750*38fd1498Szrj inline __shared_ptr<_Tp, _Lp>
751*38fd1498Szrj static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
752*38fd1498Szrj { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
753*38fd1498Szrj
754*38fd1498Szrj /* The seemingly equivalent
755*38fd1498Szrj * shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
756*38fd1498Szrj * will eventually result in undefined behaviour,
757*38fd1498Szrj * attempting to delete the same object twice.
758*38fd1498Szrj */
759*38fd1498Szrj template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
760*38fd1498Szrj inline __shared_ptr<_Tp, _Lp>
761*38fd1498Szrj const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
762*38fd1498Szrj { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
763*38fd1498Szrj
764*38fd1498Szrj /* The seemingly equivalent
765*38fd1498Szrj * shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
766*38fd1498Szrj * will eventually result in undefined behaviour,
767*38fd1498Szrj * attempting to delete the same object twice.
768*38fd1498Szrj */
769*38fd1498Szrj template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
770*38fd1498Szrj inline __shared_ptr<_Tp, _Lp>
771*38fd1498Szrj dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
772*38fd1498Szrj { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
773*38fd1498Szrj
774*38fd1498Szrj // 2.2.3.7 shared_ptr I/O
775*38fd1498Szrj template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
776*38fd1498Szrj std::basic_ostream<_Ch, _Tr>&
777*38fd1498Szrj operator<<(std::basic_ostream<_Ch, _Tr>& __os,
778*38fd1498Szrj const __shared_ptr<_Tp, _Lp>& __p)
779*38fd1498Szrj {
780*38fd1498Szrj __os << __p.get();
781*38fd1498Szrj return __os;
782*38fd1498Szrj }
783*38fd1498Szrj
784*38fd1498Szrj // 2.2.3.10 shared_ptr get_deleter (experimental)
785*38fd1498Szrj template<typename _Del, typename _Tp, _Lock_policy _Lp>
786*38fd1498Szrj inline _Del*
787*38fd1498Szrj get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
788*38fd1498Szrj {
789*38fd1498Szrj #if __cpp_rtti
790*38fd1498Szrj return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
791*38fd1498Szrj #else
792*38fd1498Szrj return 0;
793*38fd1498Szrj #endif
794*38fd1498Szrj }
795*38fd1498Szrj
796*38fd1498Szrj
797*38fd1498Szrj template<typename _Tp, _Lock_policy _Lp>
798*38fd1498Szrj class __weak_ptr
799*38fd1498Szrj {
800*38fd1498Szrj public:
801*38fd1498Szrj typedef _Tp element_type;
802*38fd1498Szrj
803*38fd1498Szrj __weak_ptr()
804*38fd1498Szrj : _M_ptr(0), _M_refcount() // never throws
805*38fd1498Szrj { }
806*38fd1498Szrj
807*38fd1498Szrj // Generated copy constructor, assignment, destructor are fine.
808*38fd1498Szrj
809*38fd1498Szrj // The "obvious" converting constructor implementation:
810*38fd1498Szrj //
811*38fd1498Szrj // template<typename _Tp1>
812*38fd1498Szrj // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
813*38fd1498Szrj // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
814*38fd1498Szrj // { }
815*38fd1498Szrj //
816*38fd1498Szrj // has a serious problem.
817*38fd1498Szrj //
818*38fd1498Szrj // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
819*38fd1498Szrj // conversion may require access to *__r._M_ptr (virtual inheritance).
820*38fd1498Szrj //
821*38fd1498Szrj // It is not possible to avoid spurious access violations since
822*38fd1498Szrj // in multithreaded programs __r._M_ptr may be invalidated at any point.
823*38fd1498Szrj template<typename _Tp1>
824*38fd1498Szrj __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
825*38fd1498Szrj : _M_refcount(__r._M_refcount) // never throws
826*38fd1498Szrj {
827*38fd1498Szrj __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
828*38fd1498Szrj _M_ptr = __r.lock().get();
829*38fd1498Szrj }
830*38fd1498Szrj
831*38fd1498Szrj template<typename _Tp1>
832*38fd1498Szrj __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
833*38fd1498Szrj : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
834*38fd1498Szrj { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
835*38fd1498Szrj
836*38fd1498Szrj template<typename _Tp1>
837*38fd1498Szrj __weak_ptr&
838*38fd1498Szrj operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
839*38fd1498Szrj {
840*38fd1498Szrj _M_ptr = __r.lock().get();
841*38fd1498Szrj _M_refcount = __r._M_refcount;
842*38fd1498Szrj return *this;
843*38fd1498Szrj }
844*38fd1498Szrj
845*38fd1498Szrj template<typename _Tp1>
846*38fd1498Szrj __weak_ptr&
847*38fd1498Szrj operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
848*38fd1498Szrj {
849*38fd1498Szrj _M_ptr = __r._M_ptr;
850*38fd1498Szrj _M_refcount = __r._M_refcount;
851*38fd1498Szrj return *this;
852*38fd1498Szrj }
853*38fd1498Szrj
854*38fd1498Szrj __shared_ptr<_Tp, _Lp>
855*38fd1498Szrj lock() const // never throws
856*38fd1498Szrj {
857*38fd1498Szrj #ifdef __GTHREADS
858*38fd1498Szrj // Optimization: avoid throw overhead.
859*38fd1498Szrj if (expired())
860*38fd1498Szrj return __shared_ptr<element_type, _Lp>();
861*38fd1498Szrj
862*38fd1498Szrj __try
863*38fd1498Szrj {
864*38fd1498Szrj return __shared_ptr<element_type, _Lp>(*this);
865*38fd1498Szrj }
866*38fd1498Szrj __catch(const bad_weak_ptr&)
867*38fd1498Szrj {
868*38fd1498Szrj // Q: How can we get here?
869*38fd1498Szrj // A: Another thread may have invalidated r after the
870*38fd1498Szrj // use_count test above.
871*38fd1498Szrj return __shared_ptr<element_type, _Lp>();
872*38fd1498Szrj }
873*38fd1498Szrj
874*38fd1498Szrj #else
875*38fd1498Szrj // Optimization: avoid try/catch overhead when single threaded.
876*38fd1498Szrj return expired() ? __shared_ptr<element_type, _Lp>()
877*38fd1498Szrj : __shared_ptr<element_type, _Lp>(*this);
878*38fd1498Szrj
879*38fd1498Szrj #endif
880*38fd1498Szrj } // XXX MT
881*38fd1498Szrj
882*38fd1498Szrj long
883*38fd1498Szrj use_count() const // never throws
884*38fd1498Szrj { return _M_refcount._M_get_use_count(); }
885*38fd1498Szrj
886*38fd1498Szrj bool
887*38fd1498Szrj expired() const // never throws
888*38fd1498Szrj { return _M_refcount._M_get_use_count() == 0; }
889*38fd1498Szrj
890*38fd1498Szrj void
891*38fd1498Szrj reset() // never throws
892*38fd1498Szrj { __weak_ptr().swap(*this); }
893*38fd1498Szrj
894*38fd1498Szrj void
895*38fd1498Szrj swap(__weak_ptr& __s) // never throws
896*38fd1498Szrj {
897*38fd1498Szrj std::swap(_M_ptr, __s._M_ptr);
898*38fd1498Szrj _M_refcount._M_swap(__s._M_refcount);
899*38fd1498Szrj }
900*38fd1498Szrj
901*38fd1498Szrj private:
902*38fd1498Szrj // Used by __enable_shared_from_this.
903*38fd1498Szrj void
904*38fd1498Szrj _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
905*38fd1498Szrj {
906*38fd1498Szrj _M_ptr = __ptr;
907*38fd1498Szrj _M_refcount = __refcount;
908*38fd1498Szrj }
909*38fd1498Szrj
910*38fd1498Szrj template<typename _Tp1>
911*38fd1498Szrj bool
912*38fd1498Szrj _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
913*38fd1498Szrj { return _M_refcount < __rhs._M_refcount; }
914*38fd1498Szrj
915*38fd1498Szrj template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
916*38fd1498Szrj template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
917*38fd1498Szrj friend class __enable_shared_from_this<_Tp, _Lp>;
918*38fd1498Szrj friend class enable_shared_from_this<_Tp>;
919*38fd1498Szrj
920*38fd1498Szrj // Friend injected into namespace and found by ADL.
921*38fd1498Szrj template<typename _Tp1>
922*38fd1498Szrj friend inline bool
923*38fd1498Szrj operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
924*38fd1498Szrj { return __lhs._M_less(__rhs); }
925*38fd1498Szrj
926*38fd1498Szrj _Tp* _M_ptr; // Contained pointer.
927*38fd1498Szrj __weak_count<_Lp> _M_refcount; // Reference counter.
928*38fd1498Szrj };
929*38fd1498Szrj
930*38fd1498Szrj // 2.2.4.7 weak_ptr specialized algorithms.
931*38fd1498Szrj template<typename _Tp, _Lock_policy _Lp>
932*38fd1498Szrj inline void
933*38fd1498Szrj swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
934*38fd1498Szrj { __a.swap(__b); }
935*38fd1498Szrj
936*38fd1498Szrj
937*38fd1498Szrj template<typename _Tp, _Lock_policy _Lp>
938*38fd1498Szrj class __enable_shared_from_this
939*38fd1498Szrj {
940*38fd1498Szrj protected:
941*38fd1498Szrj __enable_shared_from_this() { }
942*38fd1498Szrj
943*38fd1498Szrj __enable_shared_from_this(const __enable_shared_from_this&) { }
944*38fd1498Szrj
945*38fd1498Szrj __enable_shared_from_this&
946*38fd1498Szrj operator=(const __enable_shared_from_this&)
947*38fd1498Szrj { return *this; }
948*38fd1498Szrj
949*38fd1498Szrj ~__enable_shared_from_this() { }
950*38fd1498Szrj
951*38fd1498Szrj public:
952*38fd1498Szrj __shared_ptr<_Tp, _Lp>
953*38fd1498Szrj shared_from_this()
954*38fd1498Szrj { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
955*38fd1498Szrj
956*38fd1498Szrj __shared_ptr<const _Tp, _Lp>
957*38fd1498Szrj shared_from_this() const
958*38fd1498Szrj { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
959*38fd1498Szrj
960*38fd1498Szrj private:
961*38fd1498Szrj template<typename _Tp1>
962*38fd1498Szrj void
963*38fd1498Szrj _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
964*38fd1498Szrj { _M_weak_this._M_assign(__p, __n); }
965*38fd1498Szrj
966*38fd1498Szrj template<typename _Tp1>
967*38fd1498Szrj friend void
968*38fd1498Szrj __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
969*38fd1498Szrj const __enable_shared_from_this* __pe,
970*38fd1498Szrj const _Tp1* __px)
971*38fd1498Szrj {
972*38fd1498Szrj if (__pe != 0)
973*38fd1498Szrj __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
974*38fd1498Szrj }
975*38fd1498Szrj
976*38fd1498Szrj mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
977*38fd1498Szrj };
978*38fd1498Szrj
979*38fd1498Szrj
980*38fd1498Szrj // The actual shared_ptr, with forwarding constructors and
981*38fd1498Szrj // assignment operators.
982*38fd1498Szrj template<typename _Tp>
983*38fd1498Szrj class shared_ptr
984*38fd1498Szrj : public __shared_ptr<_Tp>
985*38fd1498Szrj {
986*38fd1498Szrj public:
987*38fd1498Szrj shared_ptr()
988*38fd1498Szrj : __shared_ptr<_Tp>() { }
989*38fd1498Szrj
990*38fd1498Szrj template<typename _Tp1>
991*38fd1498Szrj explicit
992*38fd1498Szrj shared_ptr(_Tp1* __p)
993*38fd1498Szrj : __shared_ptr<_Tp>(__p) { }
994*38fd1498Szrj
995*38fd1498Szrj template<typename _Tp1, typename _Deleter>
996*38fd1498Szrj shared_ptr(_Tp1* __p, _Deleter __d)
997*38fd1498Szrj : __shared_ptr<_Tp>(__p, __d) { }
998*38fd1498Szrj
999*38fd1498Szrj template<typename _Tp1>
1000*38fd1498Szrj shared_ptr(const shared_ptr<_Tp1>& __r)
1001*38fd1498Szrj : __shared_ptr<_Tp>(__r) { }
1002*38fd1498Szrj
1003*38fd1498Szrj template<typename _Tp1>
1004*38fd1498Szrj explicit
1005*38fd1498Szrj shared_ptr(const weak_ptr<_Tp1>& __r)
1006*38fd1498Szrj : __shared_ptr<_Tp>(__r) { }
1007*38fd1498Szrj
1008*38fd1498Szrj #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
1009*38fd1498Szrj template<typename _Tp1>
1010*38fd1498Szrj explicit
1011*38fd1498Szrj shared_ptr(std::auto_ptr<_Tp1>& __r)
1012*38fd1498Szrj : __shared_ptr<_Tp>(__r) { }
1013*38fd1498Szrj #endif
1014*38fd1498Szrj
1015*38fd1498Szrj template<typename _Tp1>
1016*38fd1498Szrj shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
1017*38fd1498Szrj : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
1018*38fd1498Szrj
1019*38fd1498Szrj template<typename _Tp1>
1020*38fd1498Szrj shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
1021*38fd1498Szrj : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
1022*38fd1498Szrj
1023*38fd1498Szrj template<typename _Tp1>
1024*38fd1498Szrj shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
1025*38fd1498Szrj : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
1026*38fd1498Szrj
1027*38fd1498Szrj template<typename _Tp1>
1028*38fd1498Szrj shared_ptr&
1029*38fd1498Szrj operator=(const shared_ptr<_Tp1>& __r) // never throws
1030*38fd1498Szrj {
1031*38fd1498Szrj this->__shared_ptr<_Tp>::operator=(__r);
1032*38fd1498Szrj return *this;
1033*38fd1498Szrj }
1034*38fd1498Szrj
1035*38fd1498Szrj #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED
1036*38fd1498Szrj template<typename _Tp1>
1037*38fd1498Szrj shared_ptr&
1038*38fd1498Szrj operator=(std::auto_ptr<_Tp1>& __r)
1039*38fd1498Szrj {
1040*38fd1498Szrj this->__shared_ptr<_Tp>::operator=(__r);
1041*38fd1498Szrj return *this;
1042*38fd1498Szrj }
1043*38fd1498Szrj #endif
1044*38fd1498Szrj };
1045*38fd1498Szrj
1046*38fd1498Szrj // 2.2.3.8 shared_ptr specialized algorithms.
1047*38fd1498Szrj template<typename _Tp>
1048*38fd1498Szrj inline void
1049*38fd1498Szrj swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b)
1050*38fd1498Szrj { __a.swap(__b); }
1051*38fd1498Szrj
1052*38fd1498Szrj template<typename _Tp, typename _Tp1>
1053*38fd1498Szrj inline shared_ptr<_Tp>
1054*38fd1498Szrj static_pointer_cast(const shared_ptr<_Tp1>& __r)
1055*38fd1498Szrj { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
1056*38fd1498Szrj
1057*38fd1498Szrj template<typename _Tp, typename _Tp1>
1058*38fd1498Szrj inline shared_ptr<_Tp>
1059*38fd1498Szrj const_pointer_cast(const shared_ptr<_Tp1>& __r)
1060*38fd1498Szrj { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
1061*38fd1498Szrj
1062*38fd1498Szrj template<typename _Tp, typename _Tp1>
1063*38fd1498Szrj inline shared_ptr<_Tp>
1064*38fd1498Szrj dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
1065*38fd1498Szrj { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
1066*38fd1498Szrj
1067*38fd1498Szrj
1068*38fd1498Szrj // The actual weak_ptr, with forwarding constructors and
1069*38fd1498Szrj // assignment operators.
1070*38fd1498Szrj template<typename _Tp>
1071*38fd1498Szrj class weak_ptr
1072*38fd1498Szrj : public __weak_ptr<_Tp>
1073*38fd1498Szrj {
1074*38fd1498Szrj public:
1075*38fd1498Szrj weak_ptr()
1076*38fd1498Szrj : __weak_ptr<_Tp>() { }
1077*38fd1498Szrj
1078*38fd1498Szrj template<typename _Tp1>
1079*38fd1498Szrj weak_ptr(const weak_ptr<_Tp1>& __r)
1080*38fd1498Szrj : __weak_ptr<_Tp>(__r) { }
1081*38fd1498Szrj
1082*38fd1498Szrj template<typename _Tp1>
1083*38fd1498Szrj weak_ptr(const shared_ptr<_Tp1>& __r)
1084*38fd1498Szrj : __weak_ptr<_Tp>(__r) { }
1085*38fd1498Szrj
1086*38fd1498Szrj template<typename _Tp1>
1087*38fd1498Szrj weak_ptr&
1088*38fd1498Szrj operator=(const weak_ptr<_Tp1>& __r) // never throws
1089*38fd1498Szrj {
1090*38fd1498Szrj this->__weak_ptr<_Tp>::operator=(__r);
1091*38fd1498Szrj return *this;
1092*38fd1498Szrj }
1093*38fd1498Szrj
1094*38fd1498Szrj template<typename _Tp1>
1095*38fd1498Szrj weak_ptr&
1096*38fd1498Szrj operator=(const shared_ptr<_Tp1>& __r) // never throws
1097*38fd1498Szrj {
1098*38fd1498Szrj this->__weak_ptr<_Tp>::operator=(__r);
1099*38fd1498Szrj return *this;
1100*38fd1498Szrj }
1101*38fd1498Szrj
1102*38fd1498Szrj shared_ptr<_Tp>
1103*38fd1498Szrj lock() const // never throws
1104*38fd1498Szrj {
1105*38fd1498Szrj #ifdef __GTHREADS
1106*38fd1498Szrj if (this->expired())
1107*38fd1498Szrj return shared_ptr<_Tp>();
1108*38fd1498Szrj
1109*38fd1498Szrj __try
1110*38fd1498Szrj {
1111*38fd1498Szrj return shared_ptr<_Tp>(*this);
1112*38fd1498Szrj }
1113*38fd1498Szrj __catch(const bad_weak_ptr&)
1114*38fd1498Szrj {
1115*38fd1498Szrj return shared_ptr<_Tp>();
1116*38fd1498Szrj }
1117*38fd1498Szrj #else
1118*38fd1498Szrj return this->expired() ? shared_ptr<_Tp>()
1119*38fd1498Szrj : shared_ptr<_Tp>(*this);
1120*38fd1498Szrj #endif
1121*38fd1498Szrj }
1122*38fd1498Szrj };
1123*38fd1498Szrj
1124*38fd1498Szrj template<typename _Tp>
1125*38fd1498Szrj class enable_shared_from_this
1126*38fd1498Szrj {
1127*38fd1498Szrj protected:
1128*38fd1498Szrj enable_shared_from_this() { }
1129*38fd1498Szrj
1130*38fd1498Szrj enable_shared_from_this(const enable_shared_from_this&) { }
1131*38fd1498Szrj
1132*38fd1498Szrj enable_shared_from_this&
1133*38fd1498Szrj operator=(const enable_shared_from_this&)
1134*38fd1498Szrj { return *this; }
1135*38fd1498Szrj
1136*38fd1498Szrj ~enable_shared_from_this() { }
1137*38fd1498Szrj
1138*38fd1498Szrj public:
1139*38fd1498Szrj shared_ptr<_Tp>
1140*38fd1498Szrj shared_from_this()
1141*38fd1498Szrj { return shared_ptr<_Tp>(this->_M_weak_this); }
1142*38fd1498Szrj
1143*38fd1498Szrj shared_ptr<const _Tp>
1144*38fd1498Szrj shared_from_this() const
1145*38fd1498Szrj { return shared_ptr<const _Tp>(this->_M_weak_this); }
1146*38fd1498Szrj
1147*38fd1498Szrj private:
1148*38fd1498Szrj template<typename _Tp1>
1149*38fd1498Szrj void
1150*38fd1498Szrj _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
1151*38fd1498Szrj { _M_weak_this._M_assign(__p, __n); }
1152*38fd1498Szrj
1153*38fd1498Szrj template<typename _Tp1>
1154*38fd1498Szrj friend void
1155*38fd1498Szrj __enable_shared_from_this_helper(const __shared_count<>& __pn,
1156*38fd1498Szrj const enable_shared_from_this* __pe,
1157*38fd1498Szrj const _Tp1* __px)
1158*38fd1498Szrj {
1159*38fd1498Szrj if (__pe != 0)
1160*38fd1498Szrj __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1161*38fd1498Szrj }
1162*38fd1498Szrj
1163*38fd1498Szrj mutable weak_ptr<_Tp> _M_weak_this;
1164*38fd1498Szrj };
1165*38fd1498Szrj }
1166*38fd1498Szrj
1167*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
1168*38fd1498Szrj }
1169*38fd1498Szrj
1170*38fd1498Szrj #endif // _TR1_SHARED_PTR_H
1171