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