OSDN Git Service

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