xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/tr1/shared_ptr.h (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
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
985