OSDN Git Service

2009-11-06 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / tr1 / shared_ptr.h
1 // <tr1/shared_ptr.h> -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 //  shared_count.hpp
26 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
27
28 //  shared_ptr.hpp
29 //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
30 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
31
32 //  weak_ptr.hpp
33 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
34
35 //  enable_shared_from_this.hpp
36 //  Copyright (C) 2002 Peter Dimov
37
38 // Distributed under the Boost Software License, Version 1.0. (See
39 // accompanying file LICENSE_1_0.txt or copy at
40 // http://www.boost.org/LICENSE_1_0.txt)
41
42 // GCC Note:  based on version 1.32.0 of the Boost library.
43
44 /** @file tr1/shared_ptr.h
45  *  This is an internal header file, included by other library headers.
46  *  You should not attempt to use it directly.
47  */
48
49 #ifndef _TR1_SHARED_PTR_H
50 #define _TR1_SHARED_PTR_H 1
51
52 #if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
53 #  error TR1 header cannot be included from C++0x header
54 #endif
55
56 namespace std
57 {
58 namespace tr1
59 {
60   template<typename _Ptr, typename _Deleter, _Lock_policy _Lp>
61     class _Sp_counted_base_impl
62     : public _Sp_counted_base<_Lp>
63     {
64     public:
65       // Precondition: __d(__p) must not throw.
66       _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
67       : _M_ptr(__p), _M_del(__d) { }
68     
69       virtual void
70       _M_dispose() // nothrow
71       { _M_del(_M_ptr); }
72       
73       virtual void*
74       _M_get_deleter(const std::type_info& __ti)
75       { return __ti == typeid(_Deleter) ? &_M_del : 0; }
76       
77     private:
78       _Sp_counted_base_impl(const _Sp_counted_base_impl&);
79       _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
80       
81       _Ptr      _M_ptr;  // copy constructor must not throw
82       _Deleter  _M_del;  // copy constructor must not throw
83     };
84
85   template<_Lock_policy _Lp = __default_lock_policy>
86     class __weak_count;
87
88   template<typename _Tp>
89     struct _Sp_deleter
90     {
91       typedef void result_type;
92       typedef _Tp* argument_type;
93       void operator()(_Tp* __p) const { delete __p; }
94     };
95
96   template<_Lock_policy _Lp = __default_lock_policy>
97     class __shared_count
98     {
99     public: 
100       __shared_count()
101       : _M_pi(0) // nothrow
102       { }
103   
104       template<typename _Ptr>
105         __shared_count(_Ptr __p) : _M_pi(0)
106         {
107           __try
108             {
109               typedef typename std::tr1::remove_pointer<_Ptr>::type _Tp;
110               _M_pi = new _Sp_counted_base_impl<_Ptr, _Sp_deleter<_Tp>, _Lp>(
111                   __p, _Sp_deleter<_Tp>());
112             }
113           __catch(...)
114             {
115               delete __p;
116               __throw_exception_again;
117             }
118         }
119
120       template<typename _Ptr, typename _Deleter>
121         __shared_count(_Ptr __p, _Deleter __d) : _M_pi(0)
122         {
123           __try
124             {
125               _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter, _Lp>(__p, __d);
126             }
127           __catch(...)
128             {
129               __d(__p); // Call _Deleter on __p.
130               __throw_exception_again;
131             }
132         }
133
134       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
135       template<typename _Tp>
136         explicit
137         __shared_count(std::auto_ptr<_Tp>& __r)
138         : _M_pi(new _Sp_counted_base_impl<_Tp*,
139                 _Sp_deleter<_Tp>, _Lp >(__r.get(), _Sp_deleter<_Tp>()))
140         { __r.release(); }
141
142       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
143       explicit
144       __shared_count(const __weak_count<_Lp>& __r);
145   
146       ~__shared_count() // nothrow
147       {
148         if (_M_pi != 0)
149           _M_pi->_M_release();
150       }
151       
152       __shared_count(const __shared_count& __r)
153       : _M_pi(__r._M_pi) // nothrow
154       {
155         if (_M_pi != 0)
156           _M_pi->_M_add_ref_copy();
157       }
158   
159       __shared_count&
160       operator=(const __shared_count& __r) // nothrow
161       {
162         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
163         if (__tmp != _M_pi)
164           {
165             if (__tmp != 0)
166               __tmp->_M_add_ref_copy();
167             if (_M_pi != 0)
168               _M_pi->_M_release();
169             _M_pi = __tmp;
170           }
171         return *this;
172       }
173   
174       void
175       _M_swap(__shared_count& __r) // nothrow
176       {
177         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
178         __r._M_pi = _M_pi;
179         _M_pi = __tmp;
180       }
181   
182       long
183       _M_get_use_count() const // nothrow
184       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
185
186       bool
187       _M_unique() const // nothrow
188       { return this->_M_get_use_count() == 1; }
189       
190       friend inline bool
191       operator==(const __shared_count& __a, const __shared_count& __b)
192       { return __a._M_pi == __b._M_pi; }
193   
194       friend inline bool
195       operator<(const __shared_count& __a, const __shared_count& __b)
196       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
197   
198       void*
199       _M_get_deleter(const std::type_info& __ti) const
200       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : 0; }
201
202     private:
203       friend class __weak_count<_Lp>;
204
205       _Sp_counted_base<_Lp>*  _M_pi;
206     };
207
208
209   template<_Lock_policy _Lp>
210     class __weak_count
211     {
212     public:
213       __weak_count()
214       : _M_pi(0) // nothrow
215       { }
216   
217       __weak_count(const __shared_count<_Lp>& __r)
218       : _M_pi(__r._M_pi) // nothrow
219       {
220         if (_M_pi != 0)
221           _M_pi->_M_weak_add_ref();
222       }
223       
224       __weak_count(const __weak_count<_Lp>& __r)
225       : _M_pi(__r._M_pi) // nothrow
226       {
227         if (_M_pi != 0)
228           _M_pi->_M_weak_add_ref();
229       }
230       
231       ~__weak_count() // nothrow
232       {
233         if (_M_pi != 0)
234           _M_pi->_M_weak_release();
235       }
236       
237       __weak_count<_Lp>&
238       operator=(const __shared_count<_Lp>& __r) // nothrow
239       {
240         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
241         if (__tmp != 0)
242           __tmp->_M_weak_add_ref();
243         if (_M_pi != 0)
244           _M_pi->_M_weak_release();
245         _M_pi = __tmp;  
246         return *this;
247       }
248       
249       __weak_count<_Lp>&
250       operator=(const __weak_count<_Lp>& __r) // nothrow
251       {
252         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
253         if (__tmp != 0)
254           __tmp->_M_weak_add_ref();
255         if (_M_pi != 0)
256           _M_pi->_M_weak_release();
257         _M_pi = __tmp;
258         return *this;
259       }
260
261       void
262       _M_swap(__weak_count<_Lp>& __r) // nothrow
263       {
264         _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
265         __r._M_pi = _M_pi;
266         _M_pi = __tmp;
267       }
268   
269       long
270       _M_get_use_count() const // nothrow
271       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
272
273       friend inline bool
274       operator==(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
275       { return __a._M_pi == __b._M_pi; }
276       
277       friend inline bool
278       operator<(const __weak_count<_Lp>& __a, const __weak_count<_Lp>& __b)
279       { return std::less<_Sp_counted_base<_Lp>*>()(__a._M_pi, __b._M_pi); }
280
281     private:
282       friend class __shared_count<_Lp>;
283
284       _Sp_counted_base<_Lp>*  _M_pi;
285     };
286
287   // now that __weak_count is defined we can define this constructor:
288   template<_Lock_policy _Lp>
289     inline
290     __shared_count<_Lp>::
291     __shared_count(const __weak_count<_Lp>& __r)
292     : _M_pi(__r._M_pi)
293     {
294       if (_M_pi != 0)
295         _M_pi->_M_add_ref_lock();
296       else
297         __throw_bad_weak_ptr();
298     }
299
300   // Forward declarations.
301   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
302     class __shared_ptr;
303   
304   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
305     class __weak_ptr;
306
307   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
308     class __enable_shared_from_this;
309
310   template<typename _Tp>
311     class shared_ptr;
312   
313   template<typename _Tp>
314     class weak_ptr;
315
316   template<typename _Tp>
317     class enable_shared_from_this;
318
319   // Support for enable_shared_from_this.
320
321   // Friend of __enable_shared_from_this.
322   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
323     void
324     __enable_shared_from_this_helper(const __shared_count<_Lp>&,
325                                      const __enable_shared_from_this<_Tp1,
326                                      _Lp>*, const _Tp2*);
327
328   // Friend of enable_shared_from_this.
329   template<typename _Tp1, typename _Tp2>
330     void
331     __enable_shared_from_this_helper(const __shared_count<>&,
332                                      const enable_shared_from_this<_Tp1>*,
333                                      const _Tp2*);
334
335   template<_Lock_policy _Lp>
336     inline void
337     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...)
338     { }
339
340
341   struct __static_cast_tag { };
342   struct __const_cast_tag { };
343   struct __dynamic_cast_tag { };
344
345   // A smart pointer with reference-counted copy semantics.  The
346   // object pointed to is deleted when the last shared_ptr pointing to
347   // it is destroyed or reset.
348   template<typename _Tp, _Lock_policy _Lp>
349     class __shared_ptr
350     {
351     public:
352       typedef _Tp   element_type;
353       
354       __shared_ptr()
355       : _M_ptr(0), _M_refcount() // never throws
356       { }
357
358       template<typename _Tp1>
359         explicit
360         __shared_ptr(_Tp1* __p)
361         : _M_ptr(__p), _M_refcount(__p)
362         {
363           __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
364           // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
365           __enable_shared_from_this_helper(_M_refcount, __p, __p);
366         }
367
368       template<typename _Tp1, typename _Deleter>
369         __shared_ptr(_Tp1* __p, _Deleter __d)
370         : _M_ptr(__p), _M_refcount(__p, __d)
371         {
372           __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
373           // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
374           __enable_shared_from_this_helper(_M_refcount, __p, __p);
375         }
376       
377       //  generated copy constructor, assignment, destructor are fine.
378       
379       template<typename _Tp1>
380         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
381         : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
382         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
383
384       template<typename _Tp1>
385         explicit
386         __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
387         : _M_refcount(__r._M_refcount) // may throw
388         {
389           __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
390           // It is now safe to copy __r._M_ptr, as _M_refcount(__r._M_refcount)
391           // did not throw.
392           _M_ptr = __r._M_ptr;
393         }
394
395 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
396       // Postcondition: use_count() == 1 and __r.get() == 0
397       template<typename _Tp1>
398         explicit
399         __shared_ptr(std::auto_ptr<_Tp1>& __r)
400         : _M_ptr(__r.get()), _M_refcount()
401         {
402           __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
403           // TODO requires _Tp1 is complete, delete __r.release() well-formed
404           _Tp1* __tmp = __r.get();
405           _M_refcount = __shared_count<_Lp>(__r);
406           __enable_shared_from_this_helper(_M_refcount, __tmp, __tmp);
407         }
408
409 #endif
410
411       template<typename _Tp1>
412         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __static_cast_tag)
413         : _M_ptr(static_cast<element_type*>(__r._M_ptr)),
414           _M_refcount(__r._M_refcount)
415         { }
416
417       template<typename _Tp1>
418         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __const_cast_tag)
419         : _M_ptr(const_cast<element_type*>(__r._M_ptr)),
420           _M_refcount(__r._M_refcount)
421         { }
422
423       template<typename _Tp1>
424         __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, __dynamic_cast_tag)
425         : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr)),
426           _M_refcount(__r._M_refcount)
427         {
428           if (_M_ptr == 0) // need to allocate new counter -- the cast failed
429             _M_refcount = __shared_count<_Lp>();
430         }
431
432       template<typename _Tp1>
433         __shared_ptr&
434         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
435         {
436           _M_ptr = __r._M_ptr;
437           _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
438           return *this;
439         }
440
441 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
442       template<typename _Tp1>
443         __shared_ptr&
444         operator=(std::auto_ptr<_Tp1>& __r)
445         {
446           __shared_ptr(__r).swap(*this);
447           return *this;
448         }
449 #endif
450
451       void
452       reset() // never throws
453       { __shared_ptr().swap(*this); }
454
455       template<typename _Tp1>
456         void
457         reset(_Tp1* __p) // _Tp1 must be complete.
458         {
459           // Catch self-reset errors.
460           _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); 
461           __shared_ptr(__p).swap(*this);
462         }
463
464       template<typename _Tp1, typename _Deleter>
465         void
466         reset(_Tp1* __p, _Deleter __d)
467         { __shared_ptr(__p, __d).swap(*this); }
468
469       // Allow class instantiation when _Tp is [cv-qual] void.
470       typename std::tr1::add_reference<_Tp>::type
471       operator*() const // never throws
472       {
473         _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
474         return *_M_ptr;
475       }
476
477       _Tp*
478       operator->() const // never throws
479       {
480         _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
481         return _M_ptr;
482       }
483     
484       _Tp*
485       get() const // never throws
486       { return _M_ptr; }
487
488       // Implicit conversion to "bool"
489     private:
490       typedef _Tp* __shared_ptr::*__unspecified_bool_type;
491
492     public:
493       operator __unspecified_bool_type() const // never throws
494       { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
495
496       bool
497       unique() const // never throws
498       { return _M_refcount._M_unique(); }
499
500       long
501       use_count() const // never throws
502       { return _M_refcount._M_get_use_count(); }
503
504       void
505       swap(__shared_ptr<_Tp, _Lp>& __other) // never throws
506       {
507         std::swap(_M_ptr, __other._M_ptr);
508         _M_refcount._M_swap(__other._M_refcount);
509       }
510
511     private:
512       void*
513       _M_get_deleter(const std::type_info& __ti) const
514       { return _M_refcount._M_get_deleter(__ti); }
515
516       template<typename _Tp1, _Lock_policy _Lp1>
517         bool
518         _M_less(const __shared_ptr<_Tp1, _Lp1>& __rhs) const
519         { return _M_refcount < __rhs._M_refcount; }
520
521       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
522       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
523
524       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
525         friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&);
526
527       // Friends injected into enclosing namespace and found by ADL:
528       template<typename _Tp1>
529         friend inline bool
530         operator==(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
531         { return __a.get() == __b.get(); }
532
533       template<typename _Tp1>
534         friend inline bool
535         operator!=(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
536         { return __a.get() != __b.get(); }
537
538       template<typename _Tp1>
539         friend inline bool
540         operator<(const __shared_ptr& __a, const __shared_ptr<_Tp1, _Lp>& __b)
541         { return __a._M_less(__b); }
542
543       _Tp*                 _M_ptr;         // Contained pointer.
544       __shared_count<_Lp>  _M_refcount;    // Reference counter.
545     };
546
547   // 2.2.3.8 shared_ptr specialized algorithms.
548   template<typename _Tp, _Lock_policy _Lp>
549     inline void
550     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b)
551     { __a.swap(__b); }
552
553   // 2.2.3.9 shared_ptr casts
554   /*  The seemingly equivalent
555    *           shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
556    *  will eventually result in undefined behaviour,
557    *  attempting to delete the same object twice.
558    */
559   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
560     inline __shared_ptr<_Tp, _Lp>
561     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
562     { return __shared_ptr<_Tp, _Lp>(__r, __static_cast_tag()); }
563
564   /*  The seemingly equivalent
565    *           shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
566    *  will eventually result in undefined behaviour,
567    *  attempting to delete the same object twice.
568    */
569   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
570     inline __shared_ptr<_Tp, _Lp>
571     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
572     { return __shared_ptr<_Tp, _Lp>(__r, __const_cast_tag()); }
573
574   /*  The seemingly equivalent
575    *           shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
576    *  will eventually result in undefined behaviour,
577    *  attempting to delete the same object twice.
578    */
579   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
580     inline __shared_ptr<_Tp, _Lp>
581     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r)
582     { return __shared_ptr<_Tp, _Lp>(__r, __dynamic_cast_tag()); }
583
584   // 2.2.3.7 shared_ptr I/O
585   template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
586     std::basic_ostream<_Ch, _Tr>&
587     operator<<(std::basic_ostream<_Ch, _Tr>& __os, 
588                const __shared_ptr<_Tp, _Lp>& __p)
589     {
590       __os << __p.get();
591       return __os;
592     }
593
594   // 2.2.3.10 shared_ptr get_deleter (experimental)
595   template<typename _Del, typename _Tp, _Lock_policy _Lp>
596     inline _Del*
597     get_deleter(const __shared_ptr<_Tp, _Lp>& __p)
598     { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
599
600
601   template<typename _Tp, _Lock_policy _Lp>
602     class __weak_ptr
603     {
604     public:
605       typedef _Tp element_type;
606       
607       __weak_ptr()
608       : _M_ptr(0), _M_refcount() // never throws
609       { }
610
611       // Generated copy constructor, assignment, destructor are fine.
612       
613       // The "obvious" converting constructor implementation:
614       //
615       //  template<typename _Tp1>
616       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
617       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
618       //    { }
619       //
620       // has a serious problem.
621       //
622       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
623       //  conversion may require access to *__r._M_ptr (virtual inheritance).
624       //
625       // It is not possible to avoid spurious access violations since
626       // in multithreaded programs __r._M_ptr may be invalidated at any point.
627       template<typename _Tp1>
628         __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
629         : _M_refcount(__r._M_refcount) // never throws
630         {
631           __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
632           _M_ptr = __r.lock().get();
633         }
634
635       template<typename _Tp1>
636         __weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r)
637         : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
638         { __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>) }
639
640       template<typename _Tp1>
641         __weak_ptr&
642         operator=(const __weak_ptr<_Tp1, _Lp>& __r) // never throws
643         {
644           _M_ptr = __r.lock().get();
645           _M_refcount = __r._M_refcount;
646           return *this;
647         }
648       
649       template<typename _Tp1>
650         __weak_ptr&
651         operator=(const __shared_ptr<_Tp1, _Lp>& __r) // never throws
652         {
653           _M_ptr = __r._M_ptr;
654           _M_refcount = __r._M_refcount;
655           return *this;
656         }
657
658       __shared_ptr<_Tp, _Lp>
659       lock() const // never throws
660       {
661 #ifdef __GTHREADS
662         // Optimization: avoid throw overhead.
663         if (expired())
664           return __shared_ptr<element_type, _Lp>();
665
666         __try
667           {
668             return __shared_ptr<element_type, _Lp>(*this);
669           }
670         __catch(const bad_weak_ptr&)
671           {
672             // Q: How can we get here?
673             // A: Another thread may have invalidated r after the
674             //    use_count test above.
675             return __shared_ptr<element_type, _Lp>();
676           }
677         
678 #else
679         // Optimization: avoid try/catch overhead when single threaded.
680         return expired() ? __shared_ptr<element_type, _Lp>()
681                          : __shared_ptr<element_type, _Lp>(*this);
682
683 #endif
684       } // XXX MT
685
686       long
687       use_count() const // never throws
688       { return _M_refcount._M_get_use_count(); }
689
690       bool
691       expired() const // never throws
692       { return _M_refcount._M_get_use_count() == 0; }
693       
694       void
695       reset() // never throws
696       { __weak_ptr().swap(*this); }
697
698       void
699       swap(__weak_ptr& __s) // never throws
700       {
701         std::swap(_M_ptr, __s._M_ptr);
702         _M_refcount._M_swap(__s._M_refcount);
703       }
704
705     private:
706       // Used by __enable_shared_from_this.
707       void
708       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount)
709       {
710         _M_ptr = __ptr;
711         _M_refcount = __refcount;
712       }
713
714       template<typename _Tp1>
715         bool
716         _M_less(const __weak_ptr<_Tp1, _Lp>& __rhs) const
717         { return _M_refcount < __rhs._M_refcount; }
718
719       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
720       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
721       friend class __enable_shared_from_this<_Tp, _Lp>;
722       friend class enable_shared_from_this<_Tp>;
723
724       // Friend injected into namespace and found by ADL.
725       template<typename _Tp1>
726         friend inline bool
727         operator<(const __weak_ptr& __lhs, const __weak_ptr<_Tp1, _Lp>& __rhs)
728         { return __lhs._M_less(__rhs); }
729
730       _Tp*               _M_ptr;         // Contained pointer.
731       __weak_count<_Lp>  _M_refcount;    // Reference counter.
732     };
733
734   // 2.2.4.7 weak_ptr specialized algorithms.
735   template<typename _Tp, _Lock_policy _Lp>
736     inline void
737     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b)
738     { __a.swap(__b); }
739
740
741   template<typename _Tp, _Lock_policy _Lp>
742     class __enable_shared_from_this
743     {
744     protected:
745       __enable_shared_from_this() { }
746       
747       __enable_shared_from_this(const __enable_shared_from_this&) { }
748       
749       __enable_shared_from_this&
750       operator=(const __enable_shared_from_this&)
751       { return *this; }
752
753       ~__enable_shared_from_this() { }
754       
755     public:
756       __shared_ptr<_Tp, _Lp>
757       shared_from_this()
758       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
759
760       __shared_ptr<const _Tp, _Lp>
761       shared_from_this() const
762       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
763
764     private:
765       template<typename _Tp1>
766         void
767         _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const
768         { _M_weak_this._M_assign(__p, __n); }
769
770       template<typename _Tp1>
771         friend void
772         __enable_shared_from_this_helper(const __shared_count<_Lp>& __pn,
773                                          const __enable_shared_from_this* __pe,
774                                          const _Tp1* __px)
775         {
776           if (__pe != 0)
777             __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
778         }
779
780       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
781     };
782
783
784   // The actual shared_ptr, with forwarding constructors and
785   // assignment operators.
786   template<typename _Tp>
787     class shared_ptr
788     : public __shared_ptr<_Tp>
789     {
790     public:
791       shared_ptr()
792       : __shared_ptr<_Tp>() { }
793
794       template<typename _Tp1>
795         explicit
796         shared_ptr(_Tp1* __p)
797         : __shared_ptr<_Tp>(__p) { }
798
799       template<typename _Tp1, typename _Deleter>
800         shared_ptr(_Tp1* __p, _Deleter __d)
801         : __shared_ptr<_Tp>(__p, __d) { }
802
803       template<typename _Tp1>
804         shared_ptr(const shared_ptr<_Tp1>& __r)
805         : __shared_ptr<_Tp>(__r) { }
806
807       template<typename _Tp1>
808         explicit
809         shared_ptr(const weak_ptr<_Tp1>& __r)
810         : __shared_ptr<_Tp>(__r) { }
811
812 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
813       template<typename _Tp1>
814         explicit
815         shared_ptr(std::auto_ptr<_Tp1>& __r)
816         : __shared_ptr<_Tp>(__r) { }
817 #endif
818
819       template<typename _Tp1>
820         shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
821         : __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
822
823       template<typename _Tp1>
824         shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
825         : __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
826
827       template<typename _Tp1>
828         shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
829         : __shared_ptr<_Tp>(__r, __dynamic_cast_tag()) { }
830
831       template<typename _Tp1>
832         shared_ptr&
833         operator=(const shared_ptr<_Tp1>& __r) // never throws
834         {
835           this->__shared_ptr<_Tp>::operator=(__r);
836           return *this;
837         }
838
839 #if !defined(__GXX_EXPERIMENTAL_CXX0X__) || _GLIBCXX_DEPRECATED
840       template<typename _Tp1>
841         shared_ptr&
842         operator=(std::auto_ptr<_Tp1>& __r)
843         {
844           this->__shared_ptr<_Tp>::operator=(__r);
845           return *this;
846         }
847 #endif
848     };
849
850   // 2.2.3.8 shared_ptr specialized algorithms.
851   template<typename _Tp>
852     inline void
853     swap(__shared_ptr<_Tp>& __a, __shared_ptr<_Tp>& __b)
854     { __a.swap(__b); }
855
856   template<typename _Tp, typename _Tp1>
857     inline shared_ptr<_Tp>
858     static_pointer_cast(const shared_ptr<_Tp1>& __r)
859     { return shared_ptr<_Tp>(__r, __static_cast_tag()); }
860
861   template<typename _Tp, typename _Tp1>
862     inline shared_ptr<_Tp>
863     const_pointer_cast(const shared_ptr<_Tp1>& __r)
864     { return shared_ptr<_Tp>(__r, __const_cast_tag()); }
865
866   template<typename _Tp, typename _Tp1>
867     inline shared_ptr<_Tp>
868     dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
869     { return shared_ptr<_Tp>(__r, __dynamic_cast_tag()); }
870
871
872   // The actual weak_ptr, with forwarding constructors and
873   // assignment operators.
874   template<typename _Tp>
875     class weak_ptr
876     : public __weak_ptr<_Tp>
877     {
878     public:
879       weak_ptr()
880       : __weak_ptr<_Tp>() { }
881       
882       template<typename _Tp1>
883         weak_ptr(const weak_ptr<_Tp1>& __r)
884         : __weak_ptr<_Tp>(__r) { }
885
886       template<typename _Tp1>
887         weak_ptr(const shared_ptr<_Tp1>& __r)
888         : __weak_ptr<_Tp>(__r) { }
889
890       template<typename _Tp1>
891         weak_ptr&
892         operator=(const weak_ptr<_Tp1>& __r) // never throws
893         {
894           this->__weak_ptr<_Tp>::operator=(__r);
895           return *this;
896         }
897
898       template<typename _Tp1>
899         weak_ptr&
900         operator=(const shared_ptr<_Tp1>& __r) // never throws
901         {
902           this->__weak_ptr<_Tp>::operator=(__r);
903           return *this;
904         }
905
906       shared_ptr<_Tp>
907       lock() const // never throws
908       {
909 #ifdef __GTHREADS
910         if (this->expired())
911           return shared_ptr<_Tp>();
912
913         __try
914           {
915             return shared_ptr<_Tp>(*this);
916           }
917         __catch(const bad_weak_ptr&)
918           {
919             return shared_ptr<_Tp>();
920           }
921 #else
922         return this->expired() ? shared_ptr<_Tp>()
923                                : shared_ptr<_Tp>(*this);
924 #endif
925       }
926     };
927
928   template<typename _Tp>
929     class enable_shared_from_this
930     {
931     protected:
932       enable_shared_from_this() { }
933       
934       enable_shared_from_this(const enable_shared_from_this&) { }
935
936       enable_shared_from_this&
937       operator=(const enable_shared_from_this&)
938       { return *this; }
939
940       ~enable_shared_from_this() { }
941
942     public:
943       shared_ptr<_Tp>
944       shared_from_this()
945       { return shared_ptr<_Tp>(this->_M_weak_this); }
946
947       shared_ptr<const _Tp>
948       shared_from_this() const
949       { return shared_ptr<const _Tp>(this->_M_weak_this); }
950
951     private:
952       template<typename _Tp1>
953         void
954         _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const
955         { _M_weak_this._M_assign(__p, __n); }
956
957       template<typename _Tp1>
958         friend void
959         __enable_shared_from_this_helper(const __shared_count<>& __pn,
960                                          const enable_shared_from_this* __pe,
961                                          const _Tp1* __px)
962         {
963           if (__pe != 0)
964             __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
965         }
966
967       mutable weak_ptr<_Tp>  _M_weak_this;
968     };
969 }
970 }
971
972 #endif // _TR1_SHARED_PTR_H