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