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