OSDN Git Service

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