OSDN Git Service

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