intrinsic.texi: New file.
[official-gcc.git] / libstdc++-v3 / include / tr1 / memory
blob64e2a900715a53ecdb77ad5bc0e48c4d4e4d4253
1 // <tr1/memory> -*- C++ -*-
3 // Copyright (C) 2005 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.
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.
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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
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.
30 //  boost/shared_count.hpp
31 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
33 //  shared_ptr.hpp
34 //  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
35 //  Copyright (c) 2001, 2002, 2003 Peter Dimov
37 //  weak_ptr.hpp
38 //  Copyright (c) 2001, 2002, 2003 Peter Dimov
40 //  enable_shared_from_this.hpp
41 //  Copyright (c) 2002 Peter Dimov
43 #ifndef _TR1_MEMORY
44 #define _TR1_MEMORY 1
46 #include "../memory"
47 #include <functional>       // std::less
48 #include <exception>        // std::exception
49 #include <new>              // std::bad_alloc
50 #include <typeinfo>         // std::type_info in get_deleter
51 #include <cstddef>          // std::size_t
52 #include <algorithm>        // for std::swap
53 #include <iosfwd>           // for std::basic_ostream
54 #include <cstdlib>          // for std::abort
56 #include <bits/gthr.h>
57 #include <bits/atomicity.h>
58 #include <bits/functexcept.h>
59 #include <debug/debug.h>
61 // namespace std::tr1
62 namespace std
64 namespace tr1
67 class bad_weak_ptr : public std::exception
69 public:
71   virtual char const* what() const throw()
72   {
73     return "tr1::bad_weak_ptr";
74   }
77 // Helper for exception objects in <tr1/memory>
78 // TODO this should be defined in a different file.
79 inline void
80 __throw_bad_weak_ptr()
82 #if __EXCEPTIONS
83   throw bad_weak_ptr();
84 #else
85   std::abort();
86 #endif
90 template <typename _Tp>
91   struct _Sp_deleter
92   {
93     typedef void result_type;
94     typedef _Tp* argument_type;
96     void
97     operator()(_Tp* p) const
98     { delete p; }
99   };
102 class _Sp_counted_base
104 public:
106   _Sp_counted_base()
107   : _M_use_count(1), _M_weak_count(1)
108   { }
110   virtual
111   ~_Sp_counted_base() // nothrow
112   { }
114   // dispose() is called when _M_use_count drops to zero, to release
115   // the resources managed by *this.
116   virtual void
117   dispose() = 0; // nothrow
119   // destroy() is called when _M_weak_count drops to zero.
120   virtual void
121   destroy() // nothrow
122   {
123     delete this;
124   }
126   virtual void*
127   get_deleter(const std::type_info&) = 0;
129   void
130   add_ref_copy()
131   {
132     __gnu_cxx::__atomic_add(&_M_use_count, 1);
133   }
135   void
136   add_ref_lock()
137   {
138     if (_M_use_count <= 0) // TODO not yet MT safe XXX
139     {
140       __throw_bad_weak_ptr();
141     }
142     __gnu_cxx::__atomic_add(&_M_use_count, 1);
143   }
145   void
146   release() // nothrow
147   {
148     if (__gnu_cxx::__exchange_and_add(&_M_use_count, -1) <= 1)
149     {
150       dispose();
151       weak_release();
152     }
153   }
155   void
156   weak_add_ref() // nothrow
157   {
158     __gnu_cxx::__atomic_add(&_M_weak_count, 1);
159   }
161   void
162   weak_release() // nothrow
163   {
164     if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) <= 1)
165     {
166       destroy();
167     }
168   }
170   long
171   use_count() const // nothrow
172   {
173     return _M_use_count;  // XXX is this MT safe?
174   }
176 private:
178   _Sp_counted_base(_Sp_counted_base const&);
179   _Sp_counted_base& operator= (_Sp_counted_base const&);
181   _Atomic_word _M_use_count;        // #shared
182   _Atomic_word _M_weak_count;       // #weak + (#shared != 0)
185 template <typename _Ptr, typename _Deleter>
186 class _Sp_counted_base_impl : public _Sp_counted_base
188 public:
190   /**
191    *  @brief   
192    *  @pre     d(p) must not throw.
193    */
194   _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
195   : _M_ptr(__p), _M_del(__d)
196   { }
198   virtual void
199   dispose() // nothrow
200   {
201     _M_del(_M_ptr);
202   }
204   virtual void*
205   get_deleter(const std::type_info& __ti)
206   {
207     return __ti == typeid(_Deleter) ? &_M_del : 0;
208   }
210 private:
211   _Sp_counted_base_impl(const _Sp_counted_base_impl&);
212   _Sp_counted_base_impl& operator=(const _Sp_counted_base_impl&);
214   _Ptr     _M_ptr; // copy constructor must not throw
215   _Deleter _M_del; // copy constructor must not throw
218 class weak_count;
220 class shared_count
222 private:
224   _Sp_counted_base* _M_pi;
226   friend class weak_count;
228 public:
230   shared_count()
231   : _M_pi(0) // nothrow
232   { }
234   template <typename _Ptr, typename _Deleter>
235     shared_count(_Ptr __p, _Deleter __d)
236     : _M_pi(0)
237     {
238       try
239       {
240         _M_pi = new _Sp_counted_base_impl<_Ptr, _Deleter>(__p, __d);
241       }
242       catch(...)
243       {
244         __d(__p); // delete __p
245         __throw_exception_again;
246       }
247     }
249   // auto_ptr<_Tp> is special cased to provide the strong guarantee
251   template <typename _Tp>
252     explicit shared_count(std::auto_ptr<_Tp>& __r)
253     : _M_pi(new _Sp_counted_base_impl<_Tp*,_Sp_deleter<_Tp> >(
254             __r.get(), _Sp_deleter<_Tp>()
255             ))
256     { __r.release(); }
258   // throws bad_weak_ptr when __r.use_count() == 0
259   explicit shared_count(const weak_count& __r);
261   ~shared_count() // nothrow
262   {
263     if (_M_pi != 0)
264       _M_pi->release();
265   }
267   shared_count(const shared_count& __r)
268   : _M_pi(__r._M_pi) // nothrow
269   {
270     if (_M_pi != 0)
271       _M_pi->add_ref_copy();
272   }
274   shared_count&
275   operator=(const shared_count& __r) // nothrow
276   {
277     _Sp_counted_base* __tmp = __r._M_pi;
279     if(__tmp != _M_pi)
280     {
281       if(__tmp != 0)
282         __tmp->add_ref_copy();
283       if(_M_pi != 0)
284         _M_pi->release();
285       _M_pi = __tmp;
286     }
287     return *this;
288   }
290   void swap(shared_count& __r) // nothrow
291   {
292     _Sp_counted_base* __tmp = __r._M_pi;
293     __r._M_pi = _M_pi;
294     _M_pi = __tmp;
295   }
297   long
298   use_count() const // nothrow
299   { return _M_pi != 0 ? _M_pi->use_count() : 0; }
301   bool
302   unique() const // nothrow
303   { return this->use_count() == 1; }
305   friend inline bool
306   operator==(const shared_count& __a, const shared_count& __b)
307   { return __a._M_pi == __b._M_pi; }
309   friend inline bool
310   operator<(const shared_count& __a, const shared_count& __b)
311   { return std::less<_Sp_counted_base*>()(__a._M_pi, __b._M_pi); }
313   void*
314   get_deleter(const std::type_info& __ti) const
315   { return _M_pi ? _M_pi->get_deleter(__ti) : 0; }
319 class weak_count
321 private:
323   _Sp_counted_base * _M_pi;
325   friend class shared_count;
327 public:
329   weak_count()
330   : _M_pi(0) // nothrow
331   { }
333   weak_count(const shared_count& __r)
334   : _M_pi(__r._M_pi) // nothrow
335   {
336     if (_M_pi != 0)
337       _M_pi->weak_add_ref();
338   }
340   weak_count(const weak_count& __r)
341   : _M_pi(__r._M_pi) // nothrow
342   {
343     if (_M_pi != 0)
344       _M_pi->weak_add_ref();
345   }
347   ~weak_count() // nothrow
348   {
349     if (_M_pi != 0)
350       _M_pi->weak_release();
351   }
353   weak_count&
354   operator=(const shared_count& __r) // nothrow
355   {
356     _Sp_counted_base* __tmp = __r._M_pi;
357     if (__tmp != 0)
358       __tmp->weak_add_ref();
359     if (_M_pi != 0)
360       _M_pi->weak_release();
361     _M_pi = __tmp;
363     return *this;
364   }
366   weak_count&
367   operator=(const weak_count& __r) // nothrow
368   {
369     _Sp_counted_base * __tmp = __r._M_pi;
370     if (__tmp != 0)
371       __tmp->weak_add_ref();
372     if (_M_pi != 0)
373       _M_pi->weak_release();
374     _M_pi = __tmp;
376     return *this;
377   }
379   void
380   swap(weak_count& __r) // nothrow
381   {
382     _Sp_counted_base * __tmp = __r._M_pi;
383     __r._M_pi = _M_pi;
384     _M_pi = __tmp;
385   }
387   long
388   use_count() const // nothrow
389   { return _M_pi != 0 ? _M_pi->use_count() : 0; }
391   friend inline bool
392   operator==(const weak_count& __a, const weak_count& __b)
393   { return __a._M_pi == __b._M_pi; }
395   friend inline bool
396   operator<(const weak_count& __a, const weak_count& __b)
397   { return std::less<_Sp_counted_base*>()(__a._M_pi, __b._M_pi); }
400 inline
401 shared_count::shared_count(const weak_count& __r)
402 : _M_pi(__r._M_pi)
404   if (_M_pi != 0)
405   {
406     _M_pi->add_ref_lock();
407   }
408   else
409   {
410     __throw_bad_weak_ptr();
411   }
414 // fwd decls
415 template <typename _Tp> class weak_ptr;
416 template <typename _Tp> class enable_shared_from_this;
418 struct __static_cast_tag {};
419 struct __const_cast_tag {};
420 struct __dynamic_cast_tag {};
421 struct __polymorphic_cast_tag {};
423 template<class _Tp> struct shared_ptr_traits
425     typedef _Tp & reference;
428 template<> struct shared_ptr_traits<void>
430     typedef void reference;
433 template<> struct shared_ptr_traits<void const>
435     typedef void reference;
438 template<> struct shared_ptr_traits<void volatile>
440     typedef void reference;
443 template<> struct shared_ptr_traits<void const volatile>
445     typedef void reference;
449 // enable_shared_from_this support
451 // friend of enable_shared_from_this
452 template <typename _Tp1, typename _Tp2>
453   void
454   __enable_shared_from_this( const shared_count& __pn,
455                              const enable_shared_from_this<_Tp1>* __pe,
456                              const _Tp2* __px );
458 inline void
459 __enable_shared_from_this(const shared_count&, ...)
460 { }
463  *  @class shared_ptr <tr1/memory>
465  *  A smart pointer with reference-counted copy semantics.
466  *  The object pointed to is deleted when the last shared_ptr pointing to it
467  *  is destroyed or reset.
468  */
470 template <typename _Tp>
471   class shared_ptr
472   {
473     typedef typename shared_ptr_traits<_Tp>::reference _Reference;
475   public:
477     typedef _Tp   element_type;
479     /** @brief  Construct an empty %shared_ptr.
480      *  @post   use_count()==0 && get()==0
481      */
482     shared_ptr() : _M_ptr(0), _M_refcount() // never throws
483     { }
485     /** @brief  Construct a %shared_ptr that owns the pointer @a p.
486      *  @param  p  A pointer that is convertible to element_type*.
487      *  @post   use_count()==1 && get()==p
488      *  @throw  std::bad_alloc, in which case @c delete @a p is called.
489      */
490     template <typename _Tp1>
491       explicit shared_ptr(_Tp1* __p)
492       : _M_ptr(__p), _M_refcount(__p, _Sp_deleter<_Tp1>())
493       {
494         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
495         // __glibcxx_function_requires(_CompleteConcept<_Tp1*>)
497         __enable_shared_from_this( _M_refcount, __p, __p );
498       }
500     //
501     // Requirements: D's copy constructor and destructor must not throw
502     //
503     // shared_ptr will release p by calling d(p)
504     //
505     /** @brief  Construct a %shared_ptr that owns the pointer @a p
506      *          and the deleter @a d.
507      *  @param  p  A pointer.
508      *  @param  d  A deleter.
509      *  @post   use_count()==1 && get()==p
510      *  @throw  std::bad_alloc, in which case @a d(p) is called.
511      */
512     template <typename _Tp1, typename _Deleter>
513       shared_ptr(_Tp1* __p, _Deleter __d)
514       : _M_ptr(__p), _M_refcount(__p, __d)
515       {
516         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
517         // TODO requires D is CopyConstructible and d(p) well-formed
519         __enable_shared_from_this( _M_refcount, __p, __p );
520       }
522     //  generated copy constructor, assignment, destructor are fine.
524     /** @brief  If @a r is empty, constructs an empty %shared_ptr; otherwise
525      *          construct a %shared_ptr that shares ownership with @a r.
526      *  @param  r  A %shared_ptr.
527      *  @post   get()==r.get() && use_count()==r.use_count()
528      *  @throw  std::bad_alloc, in which case 
529      */
530     template <typename _Tp1>
531       shared_ptr(const shared_ptr<_Tp1>& __r)
532       : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
533       {
534         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
535       }
537     /** @brief  Constructs a %shared_ptr that shares ownership with @a r
538      *          and stores a copy of the pointer stored in @a r.
539      *  @param  r  A weak_ptr.
540      *  @post   use_count()==r.use_count()
541      *  @throw  bad_weak_ptr when r.expired(),
542      *          in which case the constructor has no effect.
543      */
544     template <typename _Tp1>
545       explicit shared_ptr(const weak_ptr<_Tp1>& __r)
546       : _M_refcount(__r._M_refcount) // may throw
547       {
548         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
549         // it is now safe to copy r__._M_ptr, as _M_refcount(__r._M_refcount)
550         // did not throw
551         _M_ptr = __r._M_ptr;
552       }
554     /**
555      * @post use_count()==1 and r.get()==0
556      */
557     template <typename _Tp1>
558       explicit shared_ptr(std::auto_ptr<_Tp1>& __r)
559       : _M_ptr(__r.get()), _M_refcount()
560       {
561         // TODO requires r.release() convertible to _Tp*, Tp1 is complete,
562         // delete r.release() well-formed
563         _Tp1 * __tmp = __r.get();
564         _M_refcount = shared_count(__r);
566         __enable_shared_from_this( _M_refcount, __tmp, __tmp );
567       }
569     template <typename _Tp1>
570       shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
571       : _M_ptr(static_cast<element_type*>(__r._M_ptr))
572       , _M_refcount(__r._M_refcount)
573       { }
575     template <typename _Tp1>
576       shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
577       : _M_ptr(const_cast<element_type*>(__r._M_ptr))
578       , _M_refcount(__r._M_refcount)
579       { }
581     template <typename _Tp1>
582       shared_ptr(const shared_ptr<_Tp1>& __r, __dynamic_cast_tag)
583       : _M_ptr(dynamic_cast<element_type*>(__r._M_ptr))
584       , _M_refcount(__r._M_refcount)
585       {
586         if (_M_ptr == 0) // need to allocate new counter -- the cast failed
587         {
588           _M_refcount = shared_count();
589         }
590       }
592     template <typename _Tp1>
593       shared_ptr&
594       operator=(const shared_ptr<_Tp1>& __r) // never throws
595       {
596         _M_ptr = __r._M_ptr;
597         _M_refcount = __r._M_refcount; // shared_count::op= doesn't throw
598         return *this;
599       }
601     template <typename _Tp1>
602       shared_ptr&
603       operator=(std::auto_ptr<_Tp1>& __r)
604       {
605         shared_ptr(__r).swap(*this);
606         return *this;
607       }
609     void
610     reset() // never throws
611     { shared_ptr().swap(*this); }
613     template <typename _Tp1>
614       void
615       reset(_Tp1* __p) // _Tp1 must be complete
616       {
617         _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr); // catch self-reset errors
618         shared_ptr(__p).swap(*this);
619       }
621     template <typename _Tp1, typename _Deleter>
622       void
623       reset(_Tp1 * __p, _Deleter __d)
624       { shared_ptr(__p, __d).swap(*this); }
626     // error to instantiate if _Tp is [cv-qual] void
627     _Reference
628     operator*() const // never throws
629     {
630       _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
631       return *_M_ptr;
632     }
634     _Tp*
635     operator->() const // never throws
636     {
637       _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
638       return _M_ptr;
639     }
640     
641     _Tp*
642     get() const // never throws
643     { return _M_ptr; }
645     // implicit conversion to "bool"
646   private:
647     typedef _Tp* shared_ptr::*__unspecified_bool_type;
649   public:
650     operator __unspecified_bool_type() const // never throws
651     { return _M_ptr == 0 ? 0 : &shared_ptr::_M_ptr; }
653     bool
654     unique() const // never throws
655     { return _M_refcount.unique(); }
657     long
658     use_count() const // never throws
659     { return _M_refcount.use_count(); }
661     void
662     swap(shared_ptr<_Tp>& __other) // never throws
663     {
664       std::swap(_M_ptr, __other._M_ptr);
665       _M_refcount.swap(__other._M_refcount);
666     }
668   private:
669     template <typename _Tp1>
670       bool
671       _M_less(const shared_ptr<_Tp1>& __rhs) const
672       { return _M_refcount < __rhs._M_refcount; }
674     void*
675     _M_get_deleter(const std::type_info& __ti) const
676     { return _M_refcount.get_deleter(__ti); }
678     template <typename _Tp1> friend class shared_ptr;
679     template <typename _Tp1> friend class weak_ptr;
681     // friends injected into enclosing namespace and found by ADL:
683     // get_deleter (experimental)
684     template <typename _Del>
685       friend inline _Del*
686       get_deleter(const shared_ptr& __p)
687       { return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); }
689     template <typename _Tp1>
690       friend inline bool
691       operator==(const shared_ptr& __a, const shared_ptr<_Tp1>& __b)
692       { return __a.get() == __b.get(); }
694     template <typename _Tp1>
695       friend inline bool
696       operator!=(const shared_ptr& __a, const shared_ptr<_Tp1>& __b)
697       { return __a.get() != __b.get(); }
699     template <typename _Tp1>
700       friend inline bool
701       operator<(const shared_ptr& __a, const shared_ptr<_Tp1>& __b)
702       { return __a._M_less(__b); }
704     _Tp*         _M_ptr;         // contained pointer
705     shared_count _M_refcount;    // reference counter
706   };  // shared_ptr
708 // 2.2.3.9 shared_ptr casts
710 /** @warning The seemingly equivalent
711  *           <code>shared_ptr<T>(static_cast<T*>(r.get()))</code>
712  *           will eventually result in undefined behaviour,
713  *           attempting to delete the same object twice.
714  */
715 template <typename _Tp, typename _Tp1>
716   shared_ptr<_Tp>
717   static_pointer_cast(const shared_ptr<_Tp1>& __r)
718   {
719     return shared_ptr<_Tp>(__r, __static_cast_tag());
720   }
722 /** @warning The seemingly equivalent
723  *           <code>shared_ptr<T>(const_cast<T*>(r.get()))</code>
724  *           will eventually result in undefined behaviour,
725  *           attempting to delete the same object twice.
726  */
727 template <typename _Tp, typename _Tp1>
728   shared_ptr<_Tp>
729   const_pointer_cast(const shared_ptr<_Tp1>& __r)
730   {
731     return shared_ptr<_Tp>(__r, __const_cast_tag());
732   }
734 /** @warning The seemingly equivalent
735  *           <code>shared_ptr<T>(dynamic_cast<T*>(r.get()))</code>
736  *           will eventually result in undefined behaviour,
737  *           attempting to delete the same object twice.
738  */
739 template <typename _Tp, typename _Tp1>
740   shared_ptr<_Tp>
741   dynamic_pointer_cast(const shared_ptr<_Tp1>& __r)
742   {
743     return shared_ptr<_Tp>(__r, __dynamic_cast_tag());
744   }
746 // operator<<
747 template <typename _Ch, typename _Tr, typename _Tp>
748   std::basic_ostream<_Ch,_Tr>&
749   operator<<(std::basic_ostream<_Ch,_Tr>& __os, const shared_ptr<_Tp>& __p)
750   {
751     __os << __p.get();
752     return __os;
753   }
756 template <typename _Tp>
757   class weak_ptr
758   {
759   public:
761     typedef _Tp element_type;
763     weak_ptr()
764     : _M_ptr(0), _M_refcount() // never throws
765     { }
767   //  generated copy constructor, assignment, destructor are fine
769   //
770   //  The "obvious" converting constructor implementation:
771   //
772   //  template<class Y>
773   //  weak_ptr(weak_ptr<Y> const & r): _M_ptr(r._M_ptr), _M_refcount(r._M_refcount) // never throws
774   //  {
775   //  }
776   //
777   //  has a serious problem.
778   //
779   //  r._M_ptr may already have been invalidated. The _M_ptr(r._M_ptr)
780   //  conversion may require access to *r._M_ptr (virtual inheritance).
781   //
782   //  It is not possible to avoid spurious access violations since
783   //  in multithreaded programs r._M_ptr may be invalidated at any point.
784   //
786     template <typename _Tp1>
787       weak_ptr(const weak_ptr<_Tp1>& r)
788       : _M_refcount(r._M_refcount) // never throws
789       {
790         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
791         _M_ptr = r.lock().get();
792       }
794     template <typename _Tp1>
795       weak_ptr(const shared_ptr<_Tp1>& r)
796       : _M_ptr(r._M_ptr), _M_refcount(r._M_refcount) // never throws
797       {
798         __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
799       }
801     template <typename _Tp1>
802       weak_ptr&
803       operator=(const weak_ptr<_Tp1>& r) // never throws
804       {
805         _M_ptr = r.lock().get();
806         _M_refcount = r._M_refcount;
807         return *this;
808       }
810     template <typename _Tp1>
811       weak_ptr&
812       operator=(const shared_ptr<_Tp1>& r) // never throws
813       {
814         _M_ptr = r._M_ptr;
815         _M_refcount = r._M_refcount;
816         return *this;
817       }
819     shared_ptr<_Tp>
820     lock() const // never throws
821     {
822 #ifdef __GTHREADS
824       // optimization: avoid throw overhead
825       if (expired())
826       {
827         return shared_ptr<element_type>();
828       }
830       try
831       {
832         return shared_ptr<element_type>(*this);
833       }
834       catch (const bad_weak_ptr&)
835       {
836         // Q: how can we get here?
837         // A: another thread may have invalidated r after the use_count test above.
838         return shared_ptr<element_type>();
839       }
841 #else
843       // optimization: avoid try/catch overhead when single threaded
844       return expired() ? shared_ptr<element_type>() : shared_ptr<element_type>(*this);
846 #endif
847     } // XXX MT
850     long
851     use_count() const // never throws
852     { return _M_refcount.use_count(); }
854     bool
855     expired() const // never throws
856     { return _M_refcount.use_count() == 0; }
858     void
859     reset() // never throws
860     { weak_ptr().swap(*this); }
862     void
863     swap(weak_ptr& __s) // never throws
864     {
865       std::swap(_M_ptr, __s._M_ptr);
866       _M_refcount.swap(__s._M_refcount);
867     }
869   private:
871     template <typename _Tp1>
872       bool
873       _M_less(const weak_ptr<_Tp1>& __rhs) const
874       { return _M_refcount < __rhs._M_refcount; }
876     // used by __enable_shared_from_this
877     void
878     _M_assign(_Tp* __ptr, const shared_count& __refcount)
879     {
880       _M_ptr = __ptr;
881       _M_refcount = __refcount;
882     }
884     // friend injected into namespace and found by ADL
886     template <typename _Tp1>
887       friend inline bool
888       operator<(const weak_ptr& __lhs, const weak_ptr<_Tp1>& __rhs)
889       { return __lhs._M_less(__rhs); }
891     template <typename _Tp1> friend class weak_ptr;
892     template <typename _Tp1> friend class shared_ptr;
893     friend class enable_shared_from_this<_Tp>;
895     _Tp*       _M_ptr;           // contained pointer
896     weak_count _M_refcount;      // reference counter
898   };  // weak_ptr
902 template <typename _Tp>
903   class enable_shared_from_this
904   {
905   protected:
907     enable_shared_from_this()
908     { }
910     enable_shared_from_this(const enable_shared_from_this&)
911     { }
913     enable_shared_from_this&
914     operator=(const enable_shared_from_this&)
915     { return *this; }
917     ~enable_shared_from_this()
918     { }
920   public:
922     shared_ptr<_Tp>
923     shared_from_this()
924     {
925       shared_ptr<_Tp> p(this->_M_weak_this);
926       return p;
927     }
929     shared_ptr<const _Tp>
930     shared_from_this() const
931     {
932       shared_ptr<const _Tp> p(this->_M_weak_this);
933       return p;
934     }
936   private:
937     template <typename _Tp1>
938       void
939       _M_weak_assign(_Tp1* __p, const shared_count& __n) const
940       { _M_weak_this._M_assign(__p, __n); }
942     template <typename _Tp1>
943       friend void
944       __enable_shared_from_this( const shared_count& __pn, const enable_shared_from_this* __pe, const _Tp1* __px)
945       {
946         if(__pe != 0)
947           __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn);
948       }
950     mutable weak_ptr<_Tp> _M_weak_this;
951   };
953 } // namespace tr1
956  *  @brief   std::swap() specialisation for shared_ptr.
957  *  @relates shared_ptr.
958  */
959 template <typename _Tp>
960   inline void
961   swap(tr1::shared_ptr<_Tp>& __a, tr1::shared_ptr<_Tp>& __b)
962   {
963     __a.swap(__b);
964   }
967  *  @brief   std::swap() specialisation for weak_ptr.
968  *  @relates weak_ptr.
969  */
970 template <typename _Tp>
971   void
972   swap(tr1::weak_ptr<_Tp>& __a, tr1::weak_ptr<_Tp>& __b)
973   {
974     __a.swap(__b);
975   }
977 } // namespace std
979 #endif