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