OSDN Git Service

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