OSDN Git Service

2007-09-14 Jonathan Wakely <jwakely.gcc@gmail.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       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
281       template<typename _Tp>
282         explicit
283         __shared_count(std::auto_ptr<_Tp>& __r)
284         : _M_pi(new _Sp_counted_base_impl<_Tp*,
285                 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
286         { __r.release(); }
287   
288       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
289       explicit
290       __shared_count(const __weak_count<_Lp>& __r);
291   
292       ~__shared_count() // nothrow
293       {
294         if (_M_pi != 0)
295           _M_pi->_M_release();
296       }
297       
298       __shared_count(const __shared_count& __r)
299       : _M_pi(__r._M_pi) // nothrow
300       {
301         if (_M_pi != 0)
302           _M_pi->_M_add_ref_copy();
303       }
304   
305       __shared_count&
306       operator=(const __shared_count& __r) // nothrow
307       {
308         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
309         if (__tmp != _M_pi)
310           {
311             if (__tmp != 0)
312               __tmp->_M_add_ref_copy();
313             if (_M_pi != 0)
314               _M_pi->_M_release();
315             _M_pi = __tmp;
316           }
317         return *this;
318       }
319   
320       void
321       _M_swap(__shared_count& __r) // nothrow
322       {
323         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
324         __r._M_pi = _M_pi;
325         _M_pi = __tmp;
326       }
327   
328       long
329       _M_get_use_count() const // nothrow
330       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
331
332       bool
333       _M_unique() const // nothrow
334       { return this->_M_get_use_count() == 1; }
335       
336       friend inline bool
337       operator==(const __shared_count& __a, const __shared_count& __b)
338       { return __a._M_pi == __b._M_pi; }
339   
340       friend inline bool
341       operator<(const __shared_count& __a, const __shared_count& __b)
342       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
343   
344       void*
345       _M_get_deleter(const std::type_info& __ti) const
346       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
347
348     private:
349       friend class __weak_count<_Lp>;
350
351       _Sp_counted_base<_Lp>*  _M_pi;
352     };
353
354   template<_Lock_policy _Lp>
355     class __weak_count
356     {
357     public:
358       __weak_count()
359       : _M_pi(0) // nothrow
360       { }
361   
362       __weak_count(const __shared_count<_Lp>& __r)
363       : _M_pi(__r._M_pi) // nothrow
364       {
365         if (_M_pi != 0)
366           _M_pi->_M_weak_add_ref();
367       }
368       
369       __weak_count(const __weak_count<_Lp>& __r)
370       : _M_pi(__r._M_pi) // nothrow
371       {
372         if (_M_pi != 0)
373           _M_pi->_M_weak_add_ref();
374       }
375       
376       ~__weak_count() // nothrow
377       {
378         if (_M_pi != 0)
379           _M_pi->_M_weak_release();
380       }
381       
382       __weak_count<_Lp>&
383       operator=(const __shared_count<_Lp>& __r) // nothrow
384       {
385         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
386         if (__tmp != 0)
387           __tmp->_M_weak_add_ref();
388         if (_M_pi != 0)
389           _M_pi->_M_weak_release();
390         _M_pi = __tmp;  
391         return *this;
392       }
393       
394       __weak_count<_Lp>&
395       operator=(const __weak_count<_Lp>& __r) // nothrow
396       {
397         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
398         if (__tmp != 0)
399           __tmp->_M_weak_add_ref();
400         if (_M_pi != 0)
401           _M_pi->_M_weak_release();
402         _M_pi = __tmp;
403         return *this;
404       }
405
406       void
407       _M_swap(__weak_count<_Lp>& __r) // nothrow
408       {
409         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
410         __r._M_pi = _M_pi;
411         _M_pi = __tmp;
412       }
413   
414       long
415       _M_get_use_count() const // nothrow
416       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
417
418       friend inline bool
419       operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
420       { return __a._M_pi == __b._M_pi; }
421       
422       friend inline bool
423       operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
424       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
425
426     private:
427       friend class __shared_count<_Lp>;
428
429       _Sp_counted_base<_Lp>*  _M_pi;
430     };
431
432   template<_Lock_policy _Lp>
433     inline
434     __shared_count<_Lp>::
435     __shared_count(const __weak_count<_Lp>& __r)
436     : _M_pi(__r._M_pi)
437     {
438       if (_M_pi != 0)
439         _M_pi->_M_add_ref_lock();
440       else
441         __throw_bad_weak_ptr();
442     }
443   
444
445   // Forward declarations.
446   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
447     class __shared_ptr;
448   
449   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
450     class __weak_ptr;
451
452   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
453     class __enable_shared_from_this;
454
455   template<typename _Tp>
456     class shared_ptr;
457   
458   template<typename _Tp>
459     class weak_ptr;
460
461   template<typename _Tp>
462     class enable_shared_from_this;
463
464   // Support for enable_shared_from_this.
465
466   // Friend of __enable_shared_from_this.
467   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
468     void
469     __enable_shared_from_this_helper(const __shared_count<_Lp>&,
470                                      const __enable_shared_from_this<_Tp1,
471                                      _Lp>*, const _Tp2*);
472
473   // Friend of enable_shared_from_this.
474   template<typename _Tp1, typename _Tp2>
475     void
476     __enable_shared_from_this_helper(const __shared_count<>&,
477                                      const enable_shared_from_this<_Tp1>*,
478                                      const _Tp2*);
479
480   template<_Lock_policy _Lp>
481     inline void
482     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
483     { }
484
485
486   struct __static_cast_tag { };
487   struct __const_cast_tag { };
488   struct __dynamic_cast_tag { };
489
490   /**
491    *  @class shared_ptr <tr1/memory>
492    *
493    *  A smart pointer with reference-counted copy semantics.
494    *  The object pointed to is deleted when the last shared_ptr pointing to
495    *  it is destroyed or reset.
496    */
497   template<typename _Tp, _Lock_policy _Lp>
498     class __shared_ptr
499     {
500     public:
501       typedef _Tp   element_type;
502       
503       /** @brief  Construct an empty %__shared_ptr.
504        *  @post   use_count()==0 && get()==0
505        */
506       __shared_ptr()
507       : _M_ptr(0), _M_refcount() // never throws
508       { }
509
510       /** @brief  Construct a %__shared_ptr that owns the pointer @a __p.
511        *  @param  __p  A pointer that is convertible to element_type*.
512        *  @post   use_count() == 1 && get() == __p
513        *  @throw  std::bad_alloc, in which case @c delete @a __p is called.
514        */
515       template<typename _Tp1>
516         explicit
517         __shared_ptr(_Tp1* __p)
518         : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
519         {
520           __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
521           // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
522           __enable_shared_from_this_helper(_M_refcount, __p, __p);
523         }
524
525       //
526       // Requirements: _Deleter' copy constructor and destructor must not throw
527       //
528       // __shared_ptr will release __p by calling __d(__p)
529       //
530       /** @brief  Construct a %__shared_ptr that owns the pointer @a __p
531        *          and the deleter @a __d.
532        *  @param  __p  A pointer.
533        *  @param  __d  A deleter.
534        *  @post   use_count() == 1 && get() == __p
535        *  @throw  std::bad_alloc, in which case @a __d(__p) is called.
536        */
537       template<typename _Tp1, typename _Deleter>
538         __shared_ptr(_Tp1* __p, _Deleter __d)
539         : _M_ptr(__p), _M_refcount(__p, __d)
540         {
541           __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
542           // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
543           __enable_shared_from_this_helper(_M_refcount, __p, __p);
544         }
545       
546       //  generated copy constructor, assignment, destructor are fine.
547       
548       /** @brief  If @a __r is empty, constructs an empty %__shared_ptr;
549        *          otherwise construct a %__shared_ptr that shares ownership
550        *          with @a __r.
551        *  @param  __r  A %__shared_ptr.
552        *  @post   get() == __r.get() && use_count() == __r.use_count()
553        *  @throw  std::bad_alloc, in which case 
554        */
555       template<typename _Tp1>
556         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
557         : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
558         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
559
560       /** @brief  Constructs a %__shared_ptr that shares ownership with @a __r
561        *          and stores a copy of the pointer stored in @a __r.
562        *  @param  __r  A weak_ptr.
563        *  @post   use_count() == __r.use_count()
564        *  @throw  bad_weak_ptr when __r.expired(),
565        *          in which case the constructor has no effect.
566        */
567       template<typename _Tp1>
568         explicit
569         __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
570         : _M_refcount(__r._M_refcount) // may throw
571         {
572           __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
573           // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
574           // did not throw.
575           _M_ptr = __r._M_ptr;
576         }
577
578       /**
579        * @post use_count() == 1 and __r.get() == 0
580        */
581       template<typename _Tp1>
582         explicit
583         __shared_ptr(std::auto_ptr<_Tp1>& __r)
584         : _M_ptr(__r.get()), _M_refcount()
585         {
586           // TODO requires __r.release() convertible to _Tp*, _Tp1 is complete,
587           // delete __r.release() well-formed
588           _Tp1* __tmp = __r.get();
589           _M_refcount = __shared_count<_Lp>(__r);
590           __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
591         }
592
593       template<typename _Tp1>
594         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
595         : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
596           _M_refcount(__r._M_refcount)
597         { }
598
599       template<typename _Tp1>
600         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
601         : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
602           _M_refcount(__r._M_refcount)
603         { }
604
605       template<typename _Tp1>
606         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
607         : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
608           _M_refcount(__r._M_refcount)
609         {
610           if (_M_ptr == 0) // need to allocate new counter -- the cast failed
611             _M_refcount = __shared_count<_Lp>();
612         }
613       
614       template<typename _Tp1>
615         __shared_ptr&
616         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
617         {
618           _M_ptr = __r._M_ptr;
619           _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
620           return *this;
621         }
622
623       template<typename _Tp1>
624         __shared_ptr&
625         operator=(std::auto_ptr<_Tp1>& __r)
626         {
627           __shared_ptr(__r).swap(*this);
628           return *this;
629         }
630
631       void
632       reset() // never throws
633       { __shared_ptr().swap(*this); }
634
635       template<typename _Tp1>
636         void
637         reset(_Tp1* __p) // _Tp1 must be complete.
638         {
639           // Catch self-reset errors.
640           _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 
641           __shared_ptr(__p).swap(*this);
642         }
643
644       template<typename _Tp1, typename _Deleter>
645         void
646         reset(_Tp1* __p, _Deleter __d)
647         { __shared_ptr(__p, __d).swap(*this); }
648
649       // Allow class instantiation when _Tp is [cv-qual] void.
650 #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
651       typename std::add_lvalue_reference<_Tp>::type
652 #else
653       typename std::tr1::add_reference<_Tp>::type
654 #endif
655       operator*() const // never throws
656       {
657         _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
658         return *_M_ptr;
659       }
660
661       _Tp*
662       operator->() const // never throws
663       {
664         _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
665         return _M_ptr;
666       }
667     
668       _Tp*
669       get() const // never throws
670       { return _M_ptr; }
671
672       // Implicit conversion to "bool"
673     private:
674       typedef _Tp* __shared_ptr::*__unspecified_bool_type;
675
676     public:
677       operator __unspecified_bool_type() const // never throws
678       { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
679
680       bool
681       unique() const // never throws
682       { return _M_refcount._M_unique(); }
683
684       long
685       use_count() const // never throws
686       { return _M_refcount._M_get_use_count(); }
687
688       void
689       swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
690       {
691         std::swap(_M_ptr, __other._M_ptr);
692         _M_refcount._M_swap(__other._M_refcount);
693       }
694
695     private:
696       void*
697       _M_get_deleter(const std::type_info& __ti) const
698       { return _M_refcount._M_get_deleter(__ti); }
699
700       template<typename _Tp1, _Lock_policy _Lp1>
701         bool
702         _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
703         { return _M_refcount < __rhs._M_refcount; }
704
705       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
706       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
707
708       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
709         friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
710
711       // Friends injected into enclosing namespace and found by ADL:
712       template<typename _Tp1>
713         friend inline bool
714         operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
715         { return __a.get() == __b.get(); }
716
717       template<typename _Tp1>
718         friend inline bool
719         operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
720         { return __a.get() != __b.get(); }
721
722       template<typename _Tp1>
723         friend inline bool
724         operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
725         { return __a._M_less(__b); }
726
727       _Tp*                 _M_ptr;         // Contained pointer.
728       __shared_count<_Lp>  _M_refcount;    // Reference counter.
729     };
730
731   // 2.2.3.8 shared_ptr specialized algorithms.
732   template<typename _Tp, _Lock_policy _Lp>
733     inline void
734     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
735     { __a.swap(__b); }
736
737   // 2.2.3.9 shared_ptr casts
738   /** @warning The seemingly equivalent
739    *           <code>shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))</code>
740    *           will eventually result in undefined behaviour,
741    *           attempting to delete the same object twice.
742    */
743   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
744     __shared_ptr<_Tp, _Lp>
745     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
746     { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
747
748   /** @warning The seemingly equivalent
749    *           <code>shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))</code>
750    *           will eventually result in undefined behaviour,
751    *           attempting to delete the same object twice.
752    */
753   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
754     __shared_ptr<_Tp, _Lp>
755     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
756     { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
757
758   /** @warning The seemingly equivalent
759    *           <code>shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))</code>
760    *           will eventually result in undefined behaviour,
761    *           attempting to delete the same object twice.
762    */
763   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
764     __shared_ptr<_Tp, _Lp>
765     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
766     { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
767
768   // 2.2.3.7 shared_ptr I/O
769   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
770     std::basic_ostream<_Ch, _Tr>&
771     operator<<(std::basic_ostream<_Ch, _Tr>& __os, 
772                const __shared_ptr<_Tp, _Lp>& __p)
773     {
774       __os << __p.get();
775       return __os;
776     }
777
778   // 2.2.3.10 shared_ptr get_deleter (experimental)
779   template<typename _Del, typename _Tp, _Lock_policy _Lp>
780     inline _Del*
781     get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
782     { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
783
784
785   template<typename _Tp, _Lock_policy _Lp>
786     class __weak_ptr
787     {
788     public:
789       typedef _Tp element_type;
790       
791       __weak_ptr()
792       : _M_ptr(0), _M_refcount() // never throws
793       { }
794
795       // Generated copy constructor, assignment, destructor are fine.
796       
797       // The "obvious" converting constructor implementation:
798       //
799       //  template<typename _Tp1>
800       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
801       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
802       //    { }
803       //
804       // has a serious problem.
805       //
806       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
807       //  conversion may require access to *__r._M_ptr (virtual inheritance).
808       //
809       // It is not possible to avoid spurious access violations since
810       // in multithreaded programs __r._M_ptr may be invalidated at any point.
811       template<typename _Tp1>
812         __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
813         : _M_refcount(__r._M_refcount) // never throws
814         {
815           __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
816           _M_ptr = __r.lock().get();
817         }
818
819       template<typename _Tp1>
820         __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
821         : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
822         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
823
824       template<typename _Tp1>
825         __weak_ptr&
826         operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
827         {
828           _M_ptr = __r.lock().get();
829           _M_refcount = __r._M_refcount;
830           return *this;
831         }
832       
833       template<typename _Tp1>
834         __weak_ptr&
835         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
836         {
837           _M_ptr = __r._M_ptr;
838           _M_refcount = __r._M_refcount;
839           return *this;
840         }
841
842       __shared_ptr<_Tp, _Lp>
843       lock() const // never throws
844       {
845 #ifdef __GTHREADS
846         // Optimization: avoid throw overhead.
847         if (expired())
848           return __shared_ptr<element_type, _Lp>();
849
850         try
851           {
852             return __shared_ptr<element_type, _Lp>(*this);
853           }
854         catch(const bad_weak_ptr&)
855           {
856             // Q: How can we get here?
857             // A: Another thread may have invalidated r after the
858             //    use_count test above.
859             return __shared_ptr<element_type, _Lp>();
860           }
861         
862 #else
863         // Optimization: avoid try/catch overhead when single threaded.
864         return expired() ? __shared_ptr<element_type, _Lp>()
865                          : __shared_ptr<element_type, _Lp>(*this);
866
867 #endif
868       } // XXX MT
869
870       long
871       use_count() const // never throws
872       { return _M_refcount._M_get_use_count(); }
873
874       bool
875       expired() const // never throws
876       { return _M_refcount._M_get_use_count() == 0; }
877       
878       void
879       reset() // never throws
880       { __weak_ptr().swap(*this); }
881
882       void
883       swap(__weak_ptr& __s) // never throws
884       {
885         std::swap(_M_ptr, __s._M_ptr);
886         _M_refcount._M_swap(__s._M_refcount);
887       }
888
889     private:
890       // Used by __enable_shared_from_this.
891       void
892       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
893       {
894         _M_ptr = __ptr;
895         _M_refcount = __refcount;
896       }
897
898       template<typename _Tp1>
899         bool
900         _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
901         { return _M_refcount < __rhs._M_refcount; }
902
903       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
904       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
905       friend class __enable_shared_from_this<_Tp, _Lp>;
906       friend class enable_shared_from_this<_Tp>;
907
908       // Friend injected into namespace and found by ADL.
909       template<typename _Tp1>
910         friend inline bool
911         operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
912         { return __lhs._M_less(__rhs); }
913
914       _Tp*               _M_ptr;         // Contained pointer.
915       __weak_count<_Lp>  _M_refcount;    // Reference counter.
916     };
917
918   // 2.2.4.7 weak_ptr specialized algorithms.
919   template<typename _Tp, _Lock_policy _Lp>
920     inline void
921     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
922     { __a.swap(__b); }
923
924
925   template<typename _Tp, _Lock_policy _Lp>
926     class __enable_shared_from_this
927     {
928     protected:
929       __enable_shared_from_this() { }
930       
931       __enable_shared_from_this(const __enable_shared_from_this&) { }
932       
933       __enable_shared_from_this&
934       operator=(const __enable_shared_from_this&)
935       { return *this; }
936
937       ~__enable_shared_from_this() { }
938       
939     public:
940       __shared_ptr<_Tp, _Lp>
941       shared_from_this()
942       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
943
944       __shared_ptr<const _Tp, _Lp>
945       shared_from_this() const
946       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
947
948     private:
949       template<typename _Tp1>
950         void
951         _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
952         { _M_weak_this._M_assign(__p, __n); }
953
954       template<typename _Tp1>
955         friend void
956         __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
957                                          const __enable_shared_from_this* __pe,
958                                          const _Tp1* __px)
959         {
960           if (__pe != 0)
961             __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
962         }
963
964       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
965     };
966
967
968   // The actual TR1 shared_ptr, with forwarding constructors and
969   // assignment operators.
970   template<typename _Tp>
971     class shared_ptr
972     : public __shared_ptr<_Tp>
973     {
974     public:
975       shared_ptr()
976       : __shared_ptr<_Tp>() { }
977
978       template<typename _Tp1>
979         explicit
980         shared_ptr(_Tp1* __p)
981         : __shared_ptr<_Tp>(__p) { }
982
983       template<typename _Tp1, typename _Deleter>
984         shared_ptr(_Tp1* __p, _Deleter __d)
985         : __shared_ptr<_Tp>(__p, __d) { }
986
987       template<typename _Tp1>
988         shared_ptr(const shared_ptr<_Tp1>& __r)
989         : __shared_ptr<_Tp>(__r) { }
990
991       template<typename _Tp1>
992         explicit
993         shared_ptr(const weak_ptr<_Tp1>& __r)
994         : __shared_ptr<_Tp>(__r) { }
995
996       template<typename _Tp1>
997         explicit
998         shared_ptr(std::auto_ptr<_Tp1>& __r)
999         : __shared_ptr<_Tp>(__r) { }
1000
1001       template<typename _Tp1>
1002         shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
1003         : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
1004
1005       template<typename _Tp1>
1006         shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
1007         : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
1008
1009       template<typename _Tp1>
1010         shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
1011         : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
1012
1013       template<typename _Tp1>
1014         shared_ptr&
1015         operator=(const shared_ptr<_Tp1>& __r) // never throws
1016         {
1017           this->__shared_ptr<_Tp>::operator=(__r);
1018           return *this;
1019         }
1020
1021       template<typename _Tp1>
1022         shared_ptr&
1023         operator=(std::auto_ptr<_Tp1>& __r)
1024         {
1025           this->__shared_ptr<_Tp>::operator=(__r);
1026           return *this;
1027         }
1028     };
1029
1030   template<typename _Tp, typename _Tp1>
1031     shared_ptr<_Tp>
1032     static_pointer_cast(const shared_ptr<_Tp1>& __r)
1033     { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
1034
1035   template<typename _Tp, typename _Tp1>
1036     shared_ptr<_Tp>
1037     const_pointer_cast(const shared_ptr<_Tp1>& __r)
1038     { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
1039
1040   template<typename _Tp, typename _Tp1>
1041     shared_ptr<_Tp>
1042     dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
1043     { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
1044
1045
1046   // The actual TR1 weak_ptr, with forwarding constructors and
1047   // assignment operators.
1048   template<typename _Tp>
1049     class weak_ptr
1050     : public __weak_ptr<_Tp>
1051     {
1052     public:
1053       weak_ptr()
1054       : __weak_ptr<_Tp>() { }
1055       
1056       template<typename _Tp1>
1057         weak_ptr(const weak_ptr<_Tp1>& __r)
1058         : __weak_ptr<_Tp>(__r) { }
1059
1060       template<typename _Tp1>
1061         weak_ptr(const shared_ptr<_Tp1>& __r)
1062         : __weak_ptr<_Tp>(__r) { }
1063
1064       template<typename _Tp1>
1065         weak_ptr&
1066         operator=(const weak_ptr<_Tp1>& __r) // never throws
1067         {
1068           this->__weak_ptr<_Tp>::operator=(__r);
1069           return *this;
1070         }
1071
1072       template<typename _Tp1>
1073         weak_ptr&
1074         operator=(const shared_ptr<_Tp1>& __r) // never throws
1075         {
1076           this->__weak_ptr<_Tp>::operator=(__r);
1077           return *this;
1078         }
1079
1080       shared_ptr<_Tp>
1081       lock() const // never throws
1082       {
1083 #ifdef __GTHREADS
1084         if (this->expired())
1085           return shared_ptr<_Tp>();
1086
1087         try
1088           {
1089             return shared_ptr<_Tp>(*this);
1090           }
1091         catch(const bad_weak_ptr&)
1092           {
1093             return shared_ptr<_Tp>();
1094           }
1095 #else
1096         return this->expired() ? shared_ptr<_Tp>()
1097                                : shared_ptr<_Tp>(*this);
1098 #endif
1099       }
1100     };
1101
1102
1103   template<typename _Tp>
1104     class enable_shared_from_this
1105     {
1106     protected:
1107       enable_shared_from_this() { }
1108       
1109       enable_shared_from_this(const enable_shared_from_this&) { }
1110
1111       enable_shared_from_this&
1112       operator=(const enable_shared_from_this&)
1113       { return *this; }
1114
1115       ~enable_shared_from_this() { }
1116
1117     public:
1118       shared_ptr<_Tp>
1119       shared_from_this()
1120       { return shared_ptr<_Tp>(this->_M_weak_this); }
1121
1122       shared_ptr<const _Tp>
1123       shared_from_this() const
1124       { return shared_ptr<const _Tp>(this->_M_weak_this); }
1125
1126     private:
1127       template<typename _Tp1>
1128         void
1129         _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
1130         { _M_weak_this._M_assign(__p, __n); }
1131
1132       template<typename _Tp1>
1133         friend void
1134         __enable_shared_from_this_helper(const __shared_count<>& __pn,
1135                                          const enable_shared_from_this* __pe,
1136                                          const _Tp1* __px)
1137         {
1138           if (__pe != 0)
1139             __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
1140         }
1141
1142       mutable weak_ptr<_Tp>  _M_weak_this;
1143     };
1144
1145 _GLIBCXX_END_NAMESPACE_TR1
1146 }