1169691Skan// <tr1/boost_shared_ptr.h> -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4169691Skan//
5169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
6169691Skan// software; you can redistribute it and/or modify it under the
7169691Skan// terms of the GNU General Public License as published by the
8169691Skan// Free Software Foundation; either version 2, or (at your option)
9169691Skan// any later version.
10169691Skan
11169691Skan// This library is distributed in the hope that it will be useful,
12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14169691Skan// GNU General Public License for more details.
15169691Skan
16169691Skan// You should have received a copy of the GNU General Public License along
17169691Skan// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19169691Skan// USA.
20169691Skan
21169691Skan// As a special exception, you may use this file as part of a free software
22169691Skan// library without restriction.  Specifically, if other files instantiate
23169691Skan// templates or use macros or inline functions from this file, or you compile
24169691Skan// this file and link it with other files to produce an executable, this
25169691Skan// file does not by itself cause the resulting executable to be covered by
26169691Skan// the GNU General Public License.  This exception does not however
27169691Skan// invalidate any other reasons why the executable file might be covered by
28169691Skan// the GNU General Public License.
29169691Skan
30169691Skan//  shared_count.hpp
31169691Skan//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
32169691Skan
33169691Skan//  shared_ptr.hpp
34169691Skan//  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
35169691Skan//  Copyright (C) 2001, 2002, 2003 Peter Dimov
36169691Skan
37169691Skan//  weak_ptr.hpp
38169691Skan//  Copyright (C) 2001, 2002, 2003 Peter Dimov
39169691Skan
40169691Skan//  enable_shared_from_this.hpp
41169691Skan//  Copyright (C) 2002 Peter Dimov
42169691Skan
43169691Skan// Distributed under the Boost Software License, Version 1.0. (See
44169691Skan// accompanying file LICENSE_1_0.txt or copy at
45169691Skan// http://www.boost.org/LICENSE_1_0.txt)
46169691Skan
47169691Skan// GCC Note:  based on version 1.32.0 of the Boost library.
48169691Skan
49169691Skan/** @file tr1/boost_shared_ptr.h
50169691Skan *  This is an internal header file, included by other library headers.
51169691Skan *  You should not attempt to use it directly.
52169691Skan */
53169691Skan
54169691Skan#ifndef _BOOST_SHARED_PTR_H
55169691Skan#define _BOOST_SHARED_PTR_H 1
56169691Skan
57169691Skannamespace std
58169691Skan{
59169691Skan_GLIBCXX_BEGIN_NAMESPACE(tr1)
60169691Skan
61169691Skan  class bad_weak_ptr : public std::exception
62169691Skan  {
63169691Skan  public:
64169691Skan    virtual char const*
65169691Skan    what() const throw()
66169691Skan    { return "tr1::bad_weak_ptr"; }
67169691Skan  };
68169691Skan
69169691Skan  // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
70169691Skan  inline void
71169691Skan  __throw_bad_weak_ptr()
72169691Skan  {
73169691Skan#if __EXCEPTIONS
74169691Skan    throw bad_weak_ptr();
75169691Skan#else
76169691Skan    std::abort();
77169691Skan#endif
78169691Skan  }
79169691Skan
80169691Skan  using __gnu_cxx::_Lock_policy;
81169691Skan  using __gnu_cxx::__default_lock_policy;
82169691Skan  using __gnu_cxx::_S_single;
83169691Skan  using __gnu_cxx::_S_mutex;
84169691Skan  using __gnu_cxx::_S_atomic;
85169691Skan
86169691Skan  template<typename _Tp>
87169691Skan    struct _Sp_deleter
88169691Skan    {
89169691Skan      typedef void result_type;
90169691Skan      typedef _Tp* argument_type;
91169691Skan
92169691Skan      void
93169691Skan      operator()(_Tp* __p) const
94169691Skan      { delete __p; }
95169691Skan    };
96169691Skan
97169691Skan  // Empty helper class except when the template argument is _S_mutex.
98169691Skan  template<_Lock_policy _Lp>
99169691Skan    class _Mutex_base
100169691Skan    { };
101169691Skan
102169691Skan  template<>
103169691Skan    class _Mutex_base<_S_mutex>
104169691Skan    : public __gnu_cxx::__mutex
105169691Skan    { };
106169691Skan
107169691Skan  template<_Lock_policy _Lp = __default_lock_policy>
108169691Skan    class _Sp_counted_base
109169691Skan    : public _Mutex_base<_Lp>
110169691Skan    {
111169691Skan    public:
112169691Skan      _Sp_counted_base()
113169691Skan      : _M_use_count(1), _M_weak_count(1) { }
114169691Skan
115169691Skan      virtual
116169691Skan      ~_Sp_counted_base() // nothrow
117169691Skan      { }
118169691Skan
119169691Skan      // Called when _M_use_count drops to zero, to release the resources
120169691Skan      // managed by *this.
121169691Skan      virtual void
122169691Skan      _M_dispose() = 0; // nothrow
123169691Skan
124169691Skan      // Called when _M_weak_count drops to zero.
125169691Skan      virtual void
126169691Skan      _M_destroy() // nothrow
127169691Skan      { delete this; }
128169691Skan
129169691Skan      virtual void*
130169691Skan      _M_get_deleter(const std::type_info&) = 0;
131169691Skan
132169691Skan      void
133169691Skan      _M_add_ref_copy()
134169691Skan      { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
135169691Skan
136169691Skan      void
137169691Skan      _M_add_ref_lock();
138169691Skan
139169691Skan      void
140169691Skan      _M_release() // nothrow
141169691Skan      {
142169691Skan	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count,
143169691Skan						   -1) == 1)
144169691Skan	  {
145169691Skan	    _M_dispose();
146169691Skan#ifdef __GTHREADS
147169691Skan	    _GLIBCXX_READ_MEM_BARRIER;
148169691Skan	    _GLIBCXX_WRITE_MEM_BARRIER;
149169691Skan#endif
150169691Skan	    if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
151169691Skan						       -1) == 1)
152169691Skan	      _M_destroy();
153169691Skan	  }
154169691Skan      }
155169691Skan
156169691Skan      void
157169691Skan      _M_weak_add_ref() // nothrow
158169691Skan      { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
159169691Skan
160169691Skan      void
161169691Skan      _M_weak_release() // nothrow
162169691Skan      {
163169691Skan	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
164169691Skan	  {
165169691Skan#ifdef __GTHREADS
166169691Skan	    _GLIBCXX_READ_MEM_BARRIER;
167169691Skan	    _GLIBCXX_WRITE_MEM_BARRIER;
168169691Skan#endif
169169691Skan	    _M_destroy();
170169691Skan	  }
171169691Skan      }
172169691Skan
173169691Skan      long
174169691Skan      _M_get_use_count() const // nothrow
175169691Skan      { return _M_use_count; }  // XXX is this MT safe?
176169691Skan
177169691Skan    private:
178169691Skan      _Sp_counted_base(_Sp_counted_base const&);
179169691Skan      _Sp_counted_base& operator=(_Sp_counted_base const&);
180169691Skan
181169691Skan      _Atomic_word  _M_use_count;     // #shared
182169691Skan      _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
183169691Skan    };
184169691Skan
185169691Skan  template<>
186169691Skan    inline void
187169691Skan    _Sp_counted_base<_S_single>::
188169691Skan    _M_add_ref_lock()
189169691Skan    {
190169691Skan      if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
191169691Skan	{
192169691Skan	  _M_use_count = 0;
193169691Skan	  __throw_bad_weak_ptr();
194169691Skan	}
195169691Skan    }
196169691Skan
197169691Skan#ifdef __GTHREADS
198169691Skan  template<>
199169691Skan    inline void
200169691Skan    _Sp_counted_base<_S_mutex>::
201169691Skan    _M_add_ref_lock()
202169691Skan    {
203169691Skan      __gnu_cxx::__scoped_lock sentry(*this);
204169691Skan      if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
205169691Skan	{
206169691Skan	  _M_use_count = 0;
207169691Skan	  __throw_bad_weak_ptr();
208169691Skan	}
209169691Skan    }
210169691Skan#endif
211169691Skan
212169691Skan  template<>
213169691Skan    inline void
214169691Skan    _Sp_counted_base<_S_atomic>::
215169691Skan    _M_add_ref_lock()
216169691Skan    {
217169691Skan      // Perform lock-free add-if-not-zero operation.
218169691Skan      _Atomic_word __count;
219169691Skan      do
220169691Skan	{
221169691Skan	  __count = _M_use_count;
222169691Skan	  if (__count == 0)
223169691Skan	    __throw_bad_weak_ptr();
224169691Skan
225169691Skan	  // Replace the current counter value with the old value + 1, as
226169691Skan	  // long as it's not changed meanwhile.
227169691Skan	}
228169691Skan      while (!__sync_bool_compare_and_swap(&_M_use_count, __count,
229169691Skan					   __count + 1));
230169691Skan    }
231169691Skan
232169691Skan  template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
233169691Skan    class _Sp_counted_base_impl
234169691Skan    : public _Sp_counted_base<_Lp>
235169691Skan    {
236169691Skan    public:
237169691Skan      /**
238169691Skan       *  @brief
239169691Skan       *  @pre     __d(__p) must not throw.
240169691Skan       */
241169691Skan      _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
242169691Skan      : _M_ptr(__p), _M_del(__d) { }
243169691Skan
244169691Skan      virtual void
245169691Skan      _M_dispose() // nothrow
246169691Skan      { _M_del(_M_ptr); }
247169691Skan
248169691Skan      virtual void*
249169691Skan      _M_get_deleter(const std::type_info& __ti)
250169691Skan      { return __ti == typeid(_Deleter) ? &_M_del : 0; }
251169691Skan
252169691Skan    private:
253169691Skan      _Sp_counted_base_impl(const _Sp_counted_base_impl&);
254169691Skan      _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
255169691Skan
256169691Skan      _Ptr      _M_ptr;  // copy constructor must not throw
257169691Skan      _Deleter  _M_del;  // copy constructor must not throw
258169691Skan    };
259169691Skan
260169691Skan  template<_Lock_policy _Lp = __default_lock_policy>
261169691Skan    class __weak_count;
262169691Skan
263169691Skan  template<_Lock_policy _Lp = __default_lock_policy>
264169691Skan    class __shared_count
265169691Skan    {
266169691Skan    public:
267169691Skan      __shared_count()
268169691Skan      : _M_pi(0) // nothrow
269169691Skan      { }
270169691Skan
271169691Skan      template<typename _Ptr, typename _Deleter>
272169691Skan        __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
273169691Skan        {
274169691Skan	  try
275169691Skan	    {
276169691Skan	      _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
277169691Skan	    }
278169691Skan	  catch(...)
279169691Skan	    {
280169691Skan	      __d(__p); // Call _Deleter on __p.
281169691Skan	      __throw_exception_again;
282169691Skan	    }
283169691Skan	}
284169691Skan
285169691Skan      // Special case for auto_ptr<_Tp> to provide the strong guarantee.
286169691Skan      template<typename _Tp>
287169691Skan        explicit
288169691Skan        __shared_count(std::auto_ptr<_Tp>& __r)
289169691Skan	: _M_pi(new _Sp_counted_base_impl<_Tp*,
290169691Skan		_Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
291169691Skan        { __r.release(); }
292169691Skan
293169691Skan      // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
294169691Skan      explicit
295169691Skan      __shared_count(const __weak_count<_Lp>& __r);
296169691Skan
297169691Skan      ~__shared_count() // nothrow
298169691Skan      {
299169691Skan	if (_M_pi != 0)
300169691Skan	  _M_pi->_M_release();
301169691Skan      }
302169691Skan
303169691Skan      __shared_count(const __shared_count& __r)
304169691Skan      : _M_pi(__r._M_pi) // nothrow
305169691Skan      {
306169691Skan	if (_M_pi != 0)
307169691Skan	  _M_pi->_M_add_ref_copy();
308169691Skan      }
309169691Skan
310169691Skan      __shared_count&
311169691Skan      operator=(const __shared_count& __r) // nothrow
312169691Skan      {
313169691Skan	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
314169691Skan	if (__tmp != _M_pi)
315169691Skan	  {
316169691Skan	    if (__tmp != 0)
317169691Skan	      __tmp->_M_add_ref_copy();
318169691Skan	    if (_M_pi != 0)
319169691Skan	      _M_pi->_M_release();
320169691Skan	    _M_pi = __tmp;
321169691Skan	  }
322169691Skan	return *this;
323169691Skan      }
324169691Skan
325169691Skan      void
326169691Skan      _M_swap(__shared_count& __r) // nothrow
327169691Skan      {
328169691Skan	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
329169691Skan	__r._M_pi = _M_pi;
330169691Skan	_M_pi = __tmp;
331169691Skan      }
332169691Skan
333169691Skan      long
334169691Skan      _M_get_use_count() const // nothrow
335169691Skan      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
336169691Skan
337169691Skan      bool
338169691Skan      _M_unique() const // nothrow
339169691Skan      { return this->_M_get_use_count() == 1; }
340169691Skan
341169691Skan      friend inline bool
342169691Skan      operator==(const __shared_count& __a, const __shared_count& __b)
343169691Skan      { return __a._M_pi == __b._M_pi; }
344169691Skan
345169691Skan      friend inline bool
346169691Skan      operator<(const __shared_count& __a, const __shared_count& __b)
347169691Skan      { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
348169691Skan
349169691Skan      void*
350169691Skan      _M_get_deleter(const std::type_info& __ti) const
351169691Skan      { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
352169691Skan
353169691Skan    private:
354169691Skan      friend class __weak_count<_Lp>;
355169691Skan
356169691Skan      _Sp_counted_base<_Lp>*  _M_pi;
357169691Skan    };
358169691Skan
359169691Skan  template<_Lock_policy _Lp>
360169691Skan    class __weak_count
361169691Skan    {
362169691Skan    public:
363169691Skan      __weak_count()
364169691Skan      : _M_pi(0) // nothrow
365169691Skan      { }
366169691Skan
367169691Skan      __weak_count(const __shared_count<_Lp>& __r)
368169691Skan      : _M_pi(__r._M_pi) // nothrow
369169691Skan      {
370169691Skan	if (_M_pi != 0)
371169691Skan	  _M_pi->_M_weak_add_ref();
372169691Skan      }
373169691Skan
374169691Skan      __weak_count(const __weak_count<_Lp>& __r)
375169691Skan      : _M_pi(__r._M_pi) // nothrow
376169691Skan      {
377169691Skan	if (_M_pi != 0)
378169691Skan	  _M_pi->_M_weak_add_ref();
379169691Skan      }
380169691Skan
381169691Skan      ~__weak_count() // nothrow
382169691Skan      {
383169691Skan	if (_M_pi != 0)
384169691Skan	  _M_pi->_M_weak_release();
385169691Skan      }
386169691Skan
387169691Skan      __weak_count<_Lp>&
388169691Skan      operator=(const __shared_count<_Lp>& __r) // nothrow
389169691Skan      {
390169691Skan	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
391169691Skan	if (__tmp != 0)
392169691Skan	  __tmp->_M_weak_add_ref();
393169691Skan	if (_M_pi != 0)
394169691Skan	  _M_pi->_M_weak_release();
395169691Skan	_M_pi = __tmp;
396169691Skan	return *this;
397169691Skan      }
398169691Skan
399169691Skan      __weak_count<_Lp>&
400169691Skan      operator=(const __weak_count<_Lp>& __r) // nothrow
401169691Skan      {
402169691Skan	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
403169691Skan	if (__tmp != 0)
404169691Skan	  __tmp->_M_weak_add_ref();
405169691Skan	if (_M_pi != 0)
406169691Skan	  _M_pi->_M_weak_release();
407169691Skan	_M_pi = __tmp;
408169691Skan	return *this;
409169691Skan      }
410169691Skan
411169691Skan      void
412169691Skan      _M_swap(__weak_count<_Lp>& __r) // nothrow
413169691Skan      {
414169691Skan	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
415169691Skan	__r._M_pi = _M_pi;
416169691Skan	_M_pi = __tmp;
417169691Skan      }
418169691Skan
419169691Skan      long
420169691Skan      _M_get_use_count() const // nothrow
421169691Skan      { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
422169691Skan
423169691Skan      friend inline bool
424169691Skan      operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
425169691Skan      { return __a._M_pi == __b._M_pi; }
426169691Skan
427169691Skan      friend inline bool
428169691Skan      operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
429169691Skan      { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
430169691Skan
431169691Skan    private:
432169691Skan      friend class __shared_count<_Lp>;
433169691Skan
434169691Skan      _Sp_counted_base<_Lp>*  _M_pi;
435169691Skan    };
436169691Skan
437169691Skan  template<_Lock_policy _Lp>
438169691Skan    inline
439169691Skan    __shared_count<_Lp>::
440169691Skan    __shared_count(const __weak_count<_Lp>& __r)
441169691Skan    : _M_pi(__r._M_pi)
442169691Skan    {
443169691Skan      if (_M_pi != 0)
444169691Skan	_M_pi->_M_add_ref_lock();
445169691Skan      else
446169691Skan	__throw_bad_weak_ptr();
447169691Skan    }
448169691Skan
449169691Skan
450169691Skan  // Forward declarations.
451169691Skan  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
452169691Skan    class __shared_ptr;
453169691Skan
454169691Skan  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
455169691Skan    class __weak_ptr;
456169691Skan
457169691Skan  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
458169691Skan    class __enable_shared_from_this;
459169691Skan
460169691Skan  template<typename _Tp>
461169691Skan    class shared_ptr;
462169691Skan
463169691Skan  template<typename _Tp>
464169691Skan    class weak_ptr;
465169691Skan
466169691Skan  template<typename _Tp>
467169691Skan    class enable_shared_from_this;
468169691Skan
469169691Skan  // Support for enable_shared_from_this.
470169691Skan
471169691Skan  // Friend of __enable_shared_from_this.
472169691Skan  template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
473169691Skan    void
474169691Skan    __enable_shared_from_this_helper(const __shared_count<_Lp>&,
475169691Skan				     const __enable_shared_from_this<_Tp1,
476169691Skan				     _Lp>*, const _Tp2*);
477169691Skan
478169691Skan  // Friend of enable_shared_from_this.
479169691Skan  template<typename _Tp1, typename _Tp2>
480169691Skan    void
481169691Skan    __enable_shared_from_this_helper(const __shared_count<>&,
482169691Skan				     const enable_shared_from_this<_Tp1>*,
483169691Skan				     const _Tp2*);
484169691Skan
485169691Skan  template<_Lock_policy _Lp>
486169691Skan    inline void
487169691Skan    __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
488169691Skan    { }
489169691Skan
490169691Skan
491169691Skan  struct __static_cast_tag { };
492169691Skan  struct __const_cast_tag { };
493169691Skan  struct __dynamic_cast_tag { };
494169691Skan
495169691Skan  /**
496169691Skan   *  @class shared_ptr <tr1/memory>
497169691Skan   *
498169691Skan   *  A smart pointer with reference-counted copy semantics.
499169691Skan   *  The object pointed to is deleted when the last shared_ptr pointing to
500169691Skan   *  it is destroyed or reset.
501169691Skan   */
502169691Skan  template<typename _Tp, _Lock_policy _Lp>
503169691Skan    class __shared_ptr
504169691Skan    {
505169691Skan    public:
506169691Skan      typedef _Tp   element_type;
507169691Skan
508169691Skan      /** @brief  Construct an empty %__shared_ptr.
509169691Skan       *  @post   use_count()==0 && get()==0
510169691Skan       */
511169691Skan      __shared_ptr()
512169691Skan      : _M_ptr(0), _M_refcount() // never throws
513169691Skan      { }
514169691Skan
515169691Skan      /** @brief  Construct a %__shared_ptr that owns the pointer @a __p.
516169691Skan       *  @param  __p  A pointer that is convertible to element_type*.
517169691Skan       *  @post   use_count() == 1 && get() == __p
518169691Skan       *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
519169691Skan       */
520169691Skan      template<typename _Tp1>
521169691Skan        explicit
522169691Skan        __shared_ptr(_Tp1* __p)
523169691Skan	: _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
524169691Skan        {
525169691Skan	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
526169691Skan	  // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
527169691Skan	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
528169691Skan	}
529169691Skan
530169691Skan      //
531169691Skan      // Requirements: _Deleter' copy constructor and destructor must not throw
532169691Skan      //
533169691Skan      // __shared_ptr will release __p by calling __d(__p)
534169691Skan      //
535169691Skan      /** @brief  Construct a %__shared_ptr that owns the pointer @a __p
536169691Skan       *          and the deleter @a __d.
537169691Skan       *  @param  __p  A pointer.
538169691Skan       *  @param  __d  A deleter.
539169691Skan       *  @post   use_count() == 1 && get() == __p
540169691Skan       *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
541169691Skan       */
542169691Skan      template<typename _Tp1, typename _Deleter>
543169691Skan        __shared_ptr(_Tp1* __p, _Deleter __d)
544169691Skan	: _M_ptr(__p), _M_refcount(__p, __d)
545169691Skan        {
546169691Skan	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
547169691Skan	  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
548169691Skan	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
549169691Skan	}
550169691Skan
551169691Skan      //  generated copy constructor, assignment, destructor are fine.
552169691Skan
553169691Skan      /** @brief  If @a __r is empty, constructs an empty %__shared_ptr;
554169691Skan       *          otherwise construct a %__shared_ptr that shares ownership
555169691Skan       *          with @a __r.
556169691Skan       *  @param  __r  A %__shared_ptr.
557169691Skan       *  @post   get() == __r.get() && use_count() == __r.use_count()
558169691Skan       *  @throw  std::bad_alloc, in which case
559169691Skan       */
560169691Skan      template<typename _Tp1>
561169691Skan        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
562169691Skan	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
563169691Skan        { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
564169691Skan
565169691Skan      /** @brief  Constructs a %__shared_ptr that shares ownership with @a __r
566169691Skan       *          and stores a copy of the pointer stored in @a __r.
567169691Skan       *  @param  __r  A weak_ptr.
568169691Skan       *  @post   use_count() == __r.use_count()
569169691Skan       *  @throw  bad_weak_ptr when __r.expired(),
570169691Skan       *          in which case the constructor has no effect.
571169691Skan       */
572169691Skan      template<typename _Tp1>
573169691Skan        explicit
574169691Skan        __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
575169691Skan	: _M_refcount(__r._M_refcount) // may throw
576169691Skan        {
577169691Skan	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
578169691Skan	  // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
579169691Skan	  // did not throw.
580169691Skan	  _M_ptr = __r._M_ptr;
581169691Skan	}
582169691Skan
583169691Skan      /**
584169691Skan       * @post use_count() == 1 and __r.get() == 0
585169691Skan       */
586169691Skan      template<typename _Tp1>
587169691Skan        explicit
588169691Skan        __shared_ptr(std::auto_ptr<_Tp1>& __r)
589169691Skan	: _M_ptr(__r.get()), _M_refcount()
590169691Skan        {
591169691Skan	  // TODO requires __r.release() convertible to _Tp*, _Tp1 is complete,
592169691Skan	  // delete __r.release() well-formed
593169691Skan	  _Tp1* __tmp = __r.get();
594169691Skan	  _M_refcount = __shared_count<_Lp>(__r);
595169691Skan	  __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
596169691Skan	}
597169691Skan
598169691Skan      template<typename _Tp1>
599169691Skan        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
600169691Skan	: _M_ptr(static_cast<element_type*>(__r._M_ptr)),
601169691Skan	  _M_refcount(__r._M_refcount)
602169691Skan        { }
603169691Skan
604169691Skan      template<typename _Tp1>
605169691Skan        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
606169691Skan	: _M_ptr(const_cast<element_type*>(__r._M_ptr)),
607169691Skan	  _M_refcount(__r._M_refcount)
608169691Skan        { }
609169691Skan
610169691Skan      template<typename _Tp1>
611169691Skan        __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
612169691Skan	: _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
613169691Skan	  _M_refcount(__r._M_refcount)
614169691Skan        {
615169691Skan	  if (_M_ptr == 0) // need to allocate new counter -- the cast failed
616169691Skan	    _M_refcount = __shared_count<_Lp>();
617169691Skan	}
618169691Skan
619169691Skan      template<typename _Tp1>
620169691Skan        __shared_ptr&
621169691Skan        operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
622169691Skan        {
623169691Skan	  _M_ptr = __r._M_ptr;
624169691Skan	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
625169691Skan	  return *this;
626169691Skan	}
627169691Skan
628169691Skan      template<typename _Tp1>
629169691Skan        __shared_ptr&
630169691Skan        operator=(std::auto_ptr<_Tp1>& __r)
631169691Skan        {
632169691Skan	  __shared_ptr(__r).swap(*this);
633169691Skan	  return *this;
634169691Skan	}
635169691Skan
636169691Skan      void
637169691Skan      reset() // never throws
638169691Skan      { __shared_ptr().swap(*this); }
639169691Skan
640169691Skan      template<typename _Tp1>
641169691Skan        void
642169691Skan        reset(_Tp1* __p) // _Tp1 must be complete.
643169691Skan        {
644169691Skan	  // Catch self-reset errors.
645169691Skan	  _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
646169691Skan	  __shared_ptr(__p).swap(*this);
647169691Skan	}
648169691Skan
649169691Skan      template<typename _Tp1, typename _Deleter>
650169691Skan        void
651169691Skan        reset(_Tp1* __p, _Deleter __d)
652169691Skan        { __shared_ptr(__p, __d).swap(*this); }
653169691Skan
654169691Skan      // Allow class instantiation when _Tp is [cv-qual] void.
655169691Skan      typename add_reference<_Tp>::type
656169691Skan      operator*() const // never throws
657169691Skan      {
658169691Skan	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
659169691Skan	return *_M_ptr;
660169691Skan      }
661169691Skan
662169691Skan      _Tp*
663169691Skan      operator->() const // never throws
664169691Skan      {
665169691Skan	_GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
666169691Skan	return _M_ptr;
667169691Skan      }
668169691Skan
669169691Skan      _Tp*
670169691Skan      get() const // never throws
671169691Skan      { return _M_ptr; }
672169691Skan
673169691Skan      // Implicit conversion to "bool"
674169691Skan    private:
675169691Skan      typedef _Tp* __shared_ptr::*__unspecified_bool_type;
676169691Skan
677169691Skan    public:
678169691Skan      operator __unspecified_bool_type() const // never throws
679169691Skan      { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
680169691Skan
681169691Skan      bool
682169691Skan      unique() const // never throws
683169691Skan      { return _M_refcount._M_unique(); }
684169691Skan
685169691Skan      long
686169691Skan      use_count() const // never throws
687169691Skan      { return _M_refcount._M_get_use_count(); }
688169691Skan
689169691Skan      void
690169691Skan      swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
691169691Skan      {
692169691Skan	std::swap(_M_ptr, __other._M_ptr);
693169691Skan	_M_refcount._M_swap(__other._M_refcount);
694169691Skan      }
695169691Skan
696169691Skan    private:
697169691Skan      void*
698169691Skan      _M_get_deleter(const std::type_info& __ti) const
699169691Skan      { return _M_refcount._M_get_deleter(__ti); }
700169691Skan
701169691Skan      template<typename _Tp1, _Lock_policy _Lp1>
702169691Skan        bool
703169691Skan        _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
704169691Skan        { return _M_refcount < __rhs._M_refcount; }
705169691Skan
706169691Skan      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
707169691Skan      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
708169691Skan
709169691Skan      template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
710169691Skan        friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
711169691Skan
712169691Skan      // Friends injected into enclosing namespace and found by ADL:
713169691Skan      template<typename _Tp1>
714169691Skan        friend inline bool
715169691Skan        operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
716169691Skan        { return __a.get() == __b.get(); }
717169691Skan
718169691Skan      template<typename _Tp1>
719169691Skan        friend inline bool
720169691Skan        operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
721169691Skan        { return __a.get() != __b.get(); }
722169691Skan
723169691Skan      template<typename _Tp1>
724169691Skan        friend inline bool
725169691Skan        operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
726169691Skan        { return __a._M_less(__b); }
727169691Skan
728169691Skan      _Tp*         	   _M_ptr;         // Contained pointer.
729169691Skan      __shared_count<_Lp>  _M_refcount;    // Reference counter.
730169691Skan    };
731169691Skan
732169691Skan  // 2.2.3.8 shared_ptr specialized algorithms.
733169691Skan  template<typename _Tp, _Lock_policy _Lp>
734169691Skan    inline void
735169691Skan    swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
736169691Skan    { __a.swap(__b); }
737169691Skan
738169691Skan  // 2.2.3.9 shared_ptr casts
739169691Skan  /** @warning The seemingly equivalent
740169691Skan   *           <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
741169691Skan   *           will eventually result in undefined behaviour,
742169691Skan   *           attempting to delete the same object twice.
743169691Skan   */
744169691Skan  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
745169691Skan    __shared_ptr<_Tp, _Lp>
746169691Skan    static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
747169691Skan    { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
748169691Skan
749169691Skan  /** @warning The seemingly equivalent
750169691Skan   *           <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
751169691Skan   *           will eventually result in undefined behaviour,
752169691Skan   *           attempting to delete the same object twice.
753169691Skan   */
754169691Skan  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
755169691Skan    __shared_ptr<_Tp, _Lp>
756169691Skan    const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
757169691Skan    { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
758169691Skan
759169691Skan  /** @warning The seemingly equivalent
760169691Skan   *           <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
761169691Skan   *           will eventually result in undefined behaviour,
762169691Skan   *           attempting to delete the same object twice.
763169691Skan   */
764169691Skan  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
765169691Skan    __shared_ptr<_Tp, _Lp>
766169691Skan    dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
767169691Skan    { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
768169691Skan
769169691Skan  // 2.2.3.7 shared_ptr I/O
770169691Skan  template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
771169691Skan    std::basic_ostream<_Ch, _Tr>&
772169691Skan    operator<<(std::basic_ostream<_Ch, _Tr>& __os,
773169691Skan	       const __shared_ptr<_Tp, _Lp>& __p)
774169691Skan    {
775169691Skan      __os << __p.get();
776169691Skan      return __os;
777169691Skan    }
778169691Skan
779169691Skan  // 2.2.3.10 shared_ptr get_deleter (experimental)
780169691Skan  template<typename _Del, typename _Tp, _Lock_policy _Lp>
781169691Skan    inline _Del*
782169691Skan    get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
783169691Skan    { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
784169691Skan
785169691Skan
786169691Skan  template<typename _Tp, _Lock_policy _Lp>
787169691Skan    class __weak_ptr
788169691Skan    {
789169691Skan    public:
790169691Skan      typedef _Tp element_type;
791169691Skan
792169691Skan      __weak_ptr()
793169691Skan      : _M_ptr(0), _M_refcount() // never throws
794169691Skan      { }
795169691Skan
796169691Skan      // Generated copy constructor, assignment, destructor are fine.
797169691Skan
798169691Skan      // The "obvious" converting constructor implementation:
799169691Skan      //
800169691Skan      //  template<typename _Tp1>
801169691Skan      //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
802169691Skan      //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
803169691Skan      //    { }
804169691Skan      //
805169691Skan      // has a serious problem.
806169691Skan      //
807169691Skan      //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
808169691Skan      //  conversion may require access to *__r._M_ptr (virtual inheritance).
809169691Skan      //
810169691Skan      // It is not possible to avoid spurious access violations since
811169691Skan      // in multithreaded programs __r._M_ptr may be invalidated at any point.
812169691Skan      template<typename _Tp1>
813169691Skan        __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
814169691Skan	: _M_refcount(__r._M_refcount) // never throws
815169691Skan        {
816169691Skan	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
817169691Skan	  _M_ptr = __r.lock().get();
818169691Skan	}
819169691Skan
820169691Skan      template<typename _Tp1>
821169691Skan        __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
822169691Skan	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
823169691Skan        { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
824169691Skan
825169691Skan      template<typename _Tp1>
826169691Skan        __weak_ptr&
827169691Skan        operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
828169691Skan        {
829169691Skan	  _M_ptr = __r.lock().get();
830169691Skan	  _M_refcount = __r._M_refcount;
831169691Skan	  return *this;
832169691Skan	}
833169691Skan
834169691Skan      template<typename _Tp1>
835169691Skan        __weak_ptr&
836169691Skan        operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
837169691Skan        {
838169691Skan	  _M_ptr = __r._M_ptr;
839169691Skan	  _M_refcount = __r._M_refcount;
840169691Skan	  return *this;
841169691Skan	}
842169691Skan
843169691Skan      __shared_ptr<_Tp, _Lp>
844169691Skan      lock() const // never throws
845169691Skan      {
846169691Skan#ifdef __GTHREADS
847169691Skan	// Optimization: avoid throw overhead.
848169691Skan	if (expired())
849169691Skan	  return __shared_ptr<element_type, _Lp>();
850169691Skan
851169691Skan	try
852169691Skan	  {
853169691Skan	    return __shared_ptr<element_type, _Lp>(*this);
854169691Skan	  }
855169691Skan	catch(const bad_weak_ptr&)
856169691Skan	  {
857169691Skan	    // Q: How can we get here?
858169691Skan	    // A: Another thread may have invalidated r after the
859169691Skan	    //    use_count test above.
860229551Spfg	    return __shared_ptr<element_type, _Lp>();
861169691Skan	  }
862169691Skan
863169691Skan#else
864169691Skan	// Optimization: avoid try/catch overhead when single threaded.
865169691Skan	return expired() ? __shared_ptr<element_type, _Lp>()
866169691Skan	                 : __shared_ptr<element_type, _Lp>(*this);
867169691Skan
868169691Skan#endif
869169691Skan      } // XXX MT
870169691Skan
871169691Skan      long
872169691Skan      use_count() const // never throws
873169691Skan      { return _M_refcount._M_get_use_count(); }
874169691Skan
875169691Skan      bool
876169691Skan      expired() const // never throws
877169691Skan      { return _M_refcount._M_get_use_count() == 0; }
878169691Skan
879169691Skan      void
880169691Skan      reset() // never throws
881169691Skan      { __weak_ptr().swap(*this); }
882169691Skan
883169691Skan      void
884169691Skan      swap(__weak_ptr& __s) // never throws
885169691Skan      {
886169691Skan	std::swap(_M_ptr, __s._M_ptr);
887169691Skan	_M_refcount._M_swap(__s._M_refcount);
888169691Skan      }
889169691Skan
890169691Skan    private:
891169691Skan      // Used by __enable_shared_from_this.
892169691Skan      void
893169691Skan      _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
894169691Skan      {
895169691Skan	_M_ptr = __ptr;
896169691Skan	_M_refcount = __refcount;
897169691Skan      }
898169691Skan
899169691Skan      template<typename _Tp1>
900169691Skan        bool
901169691Skan        _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
902169691Skan        { return _M_refcount < __rhs._M_refcount; }
903169691Skan
904169691Skan      template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
905169691Skan      template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
906169691Skan      friend class __enable_shared_from_this<_Tp, _Lp>;
907169691Skan      friend class enable_shared_from_this<_Tp>;
908169691Skan
909169691Skan      // Friend injected into namespace and found by ADL.
910169691Skan      template<typename _Tp1>
911169691Skan        friend inline bool
912169691Skan        operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
913169691Skan        { return __lhs._M_less(__rhs); }
914169691Skan
915169691Skan      _Tp*       	 _M_ptr;         // Contained pointer.
916169691Skan      __weak_count<_Lp>  _M_refcount;    // Reference counter.
917169691Skan    };
918169691Skan
919169691Skan  // 2.2.4.7 weak_ptr specialized algorithms.
920169691Skan  template<typename _Tp, _Lock_policy _Lp>
921169691Skan    inline void
922169691Skan    swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
923169691Skan    { __a.swap(__b); }
924169691Skan
925169691Skan
926169691Skan  template<typename _Tp, _Lock_policy _Lp>
927169691Skan    class __enable_shared_from_this
928169691Skan    {
929169691Skan    protected:
930169691Skan      __enable_shared_from_this() { }
931169691Skan
932169691Skan      __enable_shared_from_this(const __enable_shared_from_this&) { }
933169691Skan
934169691Skan      __enable_shared_from_this&
935169691Skan      operator=(const __enable_shared_from_this&)
936169691Skan      { return *this; }
937169691Skan
938169691Skan      ~__enable_shared_from_this() { }
939169691Skan
940169691Skan    public:
941169691Skan      __shared_ptr<_Tp, _Lp>
942169691Skan      shared_from_this()
943169691Skan      { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
944169691Skan
945169691Skan      __shared_ptr<const _Tp, _Lp>
946169691Skan      shared_from_this() const
947169691Skan      { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
948169691Skan
949169691Skan    private:
950169691Skan      template<typename _Tp1>
951169691Skan        void
952169691Skan        _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
953169691Skan        { _M_weak_this._M_assign(__p, __n); }
954169691Skan
955169691Skan      template<typename _Tp1>
956169691Skan        friend void
957169691Skan        __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
958169691Skan					 const __enable_shared_from_this* __pe,
959169691Skan					 const _Tp1* __px)
960169691Skan        {
961169691Skan	  if (__pe != 0)
962169691Skan	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
963169691Skan	}
964169691Skan
965169691Skan      mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
966169691Skan    };
967169691Skan
968169691Skan
969169691Skan  // The actual TR1 shared_ptr, with forwarding constructors and
970169691Skan  // assignment operators.
971169691Skan  template<typename _Tp>
972169691Skan    class shared_ptr
973169691Skan    : public __shared_ptr<_Tp>
974169691Skan    {
975169691Skan    public:
976169691Skan      shared_ptr()
977169691Skan      : __shared_ptr<_Tp>() { }
978169691Skan
979169691Skan      template<typename _Tp1>
980169691Skan        explicit
981169691Skan        shared_ptr(_Tp1* __p)
982169691Skan	: __shared_ptr<_Tp>(__p) { }
983169691Skan
984169691Skan      template<typename _Tp1, typename _Deleter>
985169691Skan        shared_ptr(_Tp1* __p, _Deleter __d)
986169691Skan	: __shared_ptr<_Tp>(__p, __d) { }
987169691Skan
988169691Skan      template<typename _Tp1>
989169691Skan        shared_ptr(const shared_ptr<_Tp1>& __r)
990169691Skan	: __shared_ptr<_Tp>(__r) { }
991169691Skan
992169691Skan      template<typename _Tp1>
993169691Skan        explicit
994169691Skan        shared_ptr(const weak_ptr<_Tp1>& __r)
995169691Skan	: __shared_ptr<_Tp>(__r) { }
996169691Skan
997169691Skan      template<typename _Tp1>
998169691Skan        explicit
999169691Skan        shared_ptr(std::auto_ptr<_Tp1>& __r)
1000169691Skan	: __shared_ptr<_Tp>(__r) { }
1001169691Skan
1002169691Skan      template<typename _Tp1>
1003169691Skan        shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
1004169691Skan	: __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
1005169691Skan
1006169691Skan      template<typename _Tp1>
1007169691Skan        shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
1008169691Skan	: __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
1009169691Skan
1010169691Skan      template<typename _Tp1>
1011169691Skan        shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
1012169691Skan	: __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
1013169691Skan
1014169691Skan      template<typename _Tp1>
1015169691Skan        shared_ptr&
1016169691Skan        operator=(const shared_ptr<_Tp1>& __r) // never throws
1017169691Skan        {
1018169691Skan	  this->__shared_ptr<_Tp>::operator=(__r);
1019169691Skan	  return *this;
1020169691Skan	}
1021169691Skan
1022169691Skan      template<typename _Tp1>
1023169691Skan        shared_ptr&
1024169691Skan        operator=(std::auto_ptr<_Tp1>& __r)
1025169691Skan        {
1026169691Skan	  this->__shared_ptr<_Tp>::operator=(__r);
1027169691Skan	  return *this;
1028169691Skan	}
1029169691Skan    };
1030169691Skan
1031169691Skan  template<typename _Tp, typename _Tp1>
1032169691Skan    shared_ptr<_Tp>
1033169691Skan    static_pointer_cast(const shared_ptr<_Tp1>& __r)
1034169691Skan    { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
1035169691Skan
1036169691Skan  template<typename _Tp, typename _Tp1>
1037169691Skan    shared_ptr<_Tp>
1038169691Skan    const_pointer_cast(const shared_ptr<_Tp1>& __r)
1039169691Skan    { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
1040169691Skan
1041169691Skan  template<typename _Tp, typename _Tp1>
1042169691Skan    shared_ptr<_Tp>
1043169691Skan    dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
1044169691Skan    { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
1045169691Skan
1046169691Skan
1047169691Skan  // The actual TR1 weak_ptr, with forwarding constructors and
1048169691Skan  // assignment operators.
1049169691Skan  template<typename _Tp>
1050169691Skan    class weak_ptr
1051169691Skan    : public __weak_ptr<_Tp>
1052169691Skan    {
1053169691Skan    public:
1054169691Skan      weak_ptr()
1055169691Skan      : __weak_ptr<_Tp>() { }
1056169691Skan
1057169691Skan      template<typename _Tp1>
1058169691Skan        weak_ptr(const weak_ptr<_Tp1>& __r)
1059169691Skan	: __weak_ptr<_Tp>(__r) { }
1060169691Skan
1061169691Skan      template<typename _Tp1>
1062169691Skan        weak_ptr(const shared_ptr<_Tp1>& __r)
1063169691Skan	: __weak_ptr<_Tp>(__r) { }
1064169691Skan
1065169691Skan      template<typename _Tp1>
1066169691Skan        weak_ptr&
1067169691Skan        operator=(const weak_ptr<_Tp1>& __r) // never throws
1068169691Skan        {
1069169691Skan	  this->__weak_ptr<_Tp>::operator=(__r);
1070169691Skan	  return *this;
1071169691Skan	}
1072169691Skan
1073169691Skan      template<typename _Tp1>
1074169691Skan        weak_ptr&
1075169691Skan        operator=(const shared_ptr<_Tp1>& __r) // never throws
1076169691Skan        {
1077169691Skan	  this->__weak_ptr<_Tp>::operator=(__r);
1078169691Skan	  return *this;
1079169691Skan	}
1080169691Skan
1081169691Skan      shared_ptr<_Tp>
1082169691Skan      lock() const // never throws
1083169691Skan      {
1084169691Skan#ifdef __GTHREADS
1085169691Skan	if (this->expired())
1086169691Skan	  return shared_ptr<_Tp>();
1087169691Skan
1088169691Skan	try
1089169691Skan	  {
1090169691Skan	    return shared_ptr<_Tp>(*this);
1091169691Skan	  }
1092169691Skan	catch(const bad_weak_ptr&)
1093169691Skan	  {
1094169691Skan	    return shared_ptr<_Tp>();
1095169691Skan	  }
1096169691Skan#else
1097169691Skan	return this->expired() ? shared_ptr<_Tp>()
1098169691Skan	                       : shared_ptr<_Tp>(*this);
1099169691Skan#endif
1100169691Skan      }
1101169691Skan    };
1102169691Skan
1103169691Skan
1104169691Skan  template<typename _Tp>
1105169691Skan    class enable_shared_from_this
1106169691Skan    {
1107169691Skan    protected:
1108169691Skan      enable_shared_from_this() { }
1109169691Skan
1110169691Skan      enable_shared_from_this(const enable_shared_from_this&) { }
1111169691Skan
1112169691Skan      enable_shared_from_this&
1113169691Skan      operator=(const enable_shared_from_this&)
1114169691Skan      { return *this; }
1115169691Skan
1116169691Skan      ~enable_shared_from_this() { }
1117169691Skan
1118169691Skan    public:
1119169691Skan      shared_ptr<_Tp>
1120169691Skan      shared_from_this()
1121169691Skan      { return shared_ptr<_Tp>(this->_M_weak_this); }
1122169691Skan
1123169691Skan      shared_ptr<const _Tp>
1124169691Skan      shared_from_this() const
1125169691Skan      { return shared_ptr<const _Tp>(this->_M_weak_this); }
1126169691Skan
1127169691Skan    private:
1128169691Skan      template<typename _Tp1>
1129169691Skan        void
1130169691Skan        _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
1131169691Skan        { _M_weak_this._M_assign(__p, __n); }
1132169691Skan
1133169691Skan      template<typename _Tp1>
1134169691Skan        friend void
1135169691Skan        __enable_shared_from_this_helper(const __shared_count<>& __pn,
1136169691Skan					 const enable_shared_from_this* __pe,
1137169691Skan					 const _Tp1* __px)
1138169691Skan        {
1139169691Skan	  if (__pe != 0)
1140169691Skan	    __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1141169691Skan	}
1142169691Skan
1143169691Skan      mutable weak_ptr<_Tp>  _M_weak_this;
1144169691Skan    };
1145169691Skan
1146169691Skan_GLIBCXX_END_NAMESPACE
1147169691Skan} // namespace std
1148169691Skan
1149169691Skan#endif
1150