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