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 {
_GLIBCXX_BEGIN_NAMESPACE(tr1)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
__throw_bad_weak_ptr()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
operator_Sp_deleter93       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:
_Sp_counted_base()112       _Sp_counted_base()
113       : _M_use_count(1), _M_weak_count(1) { }
114 
115       virtual
~_Sp_counted_base()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
_M_destroy()126       _M_destroy() // nothrow
127       { delete this; }
128 
129       virtual void*
130       _M_get_deleter(const std::type_info&) = 0;
131 
132       void
_M_add_ref_copy()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
_M_release()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
_M_weak_add_ref()157       _M_weak_add_ref() // nothrow
158       { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
159 
160       void
_M_weak_release()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
_M_get_use_count()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>::
_M_add_ref_lock()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>::
_M_add_ref_lock()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>::
_M_add_ref_lock()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        */
_Sp_counted_base_impl(_Ptr __p,_Deleter __d)241       _Sp_counted_base_impl(_Ptr __p, _Deleter __d)
242       : _M_ptr(__p), _M_del(__d) { }
243 
244       virtual void
_M_dispose()245       _M_dispose() // nothrow
246       { _M_del(_M_ptr); }
247 
248       virtual void*
_M_get_deleter(const std::type_info & __ti)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:
__shared_count()267       __shared_count()
268       : _M_pi(0) // nothrow
269       { }
270 
271       template<typename _Ptr, typename _Deleter>
__shared_count(_Ptr __p,_Deleter __d)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
__shared_count(std::auto_ptr<_Tp> & __r)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 
~__shared_count()297       ~__shared_count() // nothrow
298       {
299 	if (_M_pi != 0)
300 	  _M_pi->_M_release();
301       }
302 
__shared_count(const __shared_count & __r)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
_M_swap(__shared_count & __r)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
_M_get_use_count()334       _M_get_use_count() const // nothrow
335       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
336 
337       bool
_M_unique()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*
_M_get_deleter(const std::type_info & __ti)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:
__weak_count()363       __weak_count()
364       : _M_pi(0) // nothrow
365       { }
366 
__weak_count(const __shared_count<_Lp> & __r)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 
__weak_count(const __weak_count<_Lp> & __r)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 
~__weak_count()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
_M_swap(__weak_count<_Lp> & __r)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
_M_get_use_count()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>::
__shared_count(const __weak_count<_Lp> & __r)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
__enable_shared_from_this_helper(const __shared_count<_Lp> &,...)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        */
__shared_ptr()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
__shared_ptr(_Tp1 * __p)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>
__shared_ptr(_Tp1 * __p,_Deleter __d)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>
__shared_ptr(const __shared_ptr<_Tp1,_Lp> & __r)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
__shared_ptr(const __weak_ptr<_Tp1,_Lp> & __r)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
__shared_ptr(std::auto_ptr<_Tp1> & __r)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>
__shared_ptr(const __shared_ptr<_Tp1,_Lp> & __r,__static_cast_tag)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>
__shared_ptr(const __shared_ptr<_Tp1,_Lp> & __r,__const_cast_tag)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>
__shared_ptr(const __shared_ptr<_Tp1,_Lp> & __r,__dynamic_cast_tag)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
reset()637       reset() // never throws
638       { __shared_ptr().swap(*this); }
639 
640       template<typename _Tp1>
641         void
reset(_Tp1 * __p)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
reset(_Tp1 * __p,_Deleter __d)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*
get()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:
__unspecified_bool_type()678       operator __unspecified_bool_type() const // never throws
679       { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
680 
681       bool
unique()682       unique() const // never throws
683       { return _M_refcount._M_unique(); }
684 
685       long
use_count()686       use_count() const // never throws
687       { return _M_refcount._M_get_use_count(); }
688 
689       void
swap(__shared_ptr<_Tp,_Lp> & __other)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*
_M_get_deleter(const std::type_info & __ti)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
_M_less(const __shared_ptr<_Tp1,_Lp1> & __rhs)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
swap(__shared_ptr<_Tp,_Lp> & __a,__shared_ptr<_Tp,_Lp> & __b)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>
static_pointer_cast(const __shared_ptr<_Tp1,_Lp> & __r)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>
const_pointer_cast(const __shared_ptr<_Tp1,_Lp> & __r)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>
dynamic_pointer_cast(const __shared_ptr<_Tp1,_Lp> & __r)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*
get_deleter(const __shared_ptr<_Tp,_Lp> & __p)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 
__weak_ptr()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>
__weak_ptr(const __weak_ptr<_Tp1,_Lp> & __r)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>
__weak_ptr(const __shared_ptr<_Tp1,_Lp> & __r)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>
lock()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>();
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
use_count()872       use_count() const // never throws
873       { return _M_refcount._M_get_use_count(); }
874 
875       bool
expired()876       expired() const // never throws
877       { return _M_refcount._M_get_use_count() == 0; }
878 
879       void
reset()880       reset() // never throws
881       { __weak_ptr().swap(*this); }
882 
883       void
swap(__weak_ptr & __s)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
_M_assign(_Tp * __ptr,const __shared_count<_Lp> & __refcount)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
_M_less(const __weak_ptr<_Tp1,_Lp> & __rhs)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
swap(__weak_ptr<_Tp,_Lp> & __a,__weak_ptr<_Tp,_Lp> & __b)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:
__enable_shared_from_this()930       __enable_shared_from_this() { }
931 
__enable_shared_from_this(const __enable_shared_from_this &)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 
~__enable_shared_from_this()938       ~__enable_shared_from_this() { }
939 
940     public:
941       __shared_ptr<_Tp, _Lp>
shared_from_this()942       shared_from_this()
943       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
944 
945       __shared_ptr<const _Tp, _Lp>
shared_from_this()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
_M_weak_assign(_Tp1 * __p,const __shared_count<_Lp> & __n)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
__enable_shared_from_this_helper(const __shared_count<_Lp> & __pn,const __enable_shared_from_this * __pe,const _Tp1 * __px)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:
shared_ptr()976       shared_ptr()
977       : __shared_ptr<_Tp>() { }
978 
979       template<typename _Tp1>
980         explicit
shared_ptr(_Tp1 * __p)981         shared_ptr(_Tp1* __p)
982 	: __shared_ptr<_Tp>(__p) { }
983 
984       template<typename _Tp1, typename _Deleter>
shared_ptr(_Tp1 * __p,_Deleter __d)985         shared_ptr(_Tp1* __p, _Deleter __d)
986 	: __shared_ptr<_Tp>(__p, __d) { }
987 
988       template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1> & __r)989         shared_ptr(const shared_ptr<_Tp1>& __r)
990 	: __shared_ptr<_Tp>(__r) { }
991 
992       template<typename _Tp1>
993         explicit
shared_ptr(const weak_ptr<_Tp1> & __r)994         shared_ptr(const weak_ptr<_Tp1>& __r)
995 	: __shared_ptr<_Tp>(__r) { }
996 
997       template<typename _Tp1>
998         explicit
shared_ptr(std::auto_ptr<_Tp1> & __r)999         shared_ptr(std::auto_ptr<_Tp1>& __r)
1000 	: __shared_ptr<_Tp>(__r) { }
1001 
1002       template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1> & __r,__static_cast_tag)1003         shared_ptr(const shared_ptr<_Tp1>& __r, __static_cast_tag)
1004 	: __shared_ptr<_Tp>(__r, __static_cast_tag()) { }
1005 
1006       template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1> & __r,__const_cast_tag)1007         shared_ptr(const shared_ptr<_Tp1>& __r, __const_cast_tag)
1008 	: __shared_ptr<_Tp>(__r, __const_cast_tag()) { }
1009 
1010       template<typename _Tp1>
shared_ptr(const shared_ptr<_Tp1> & __r,__dynamic_cast_tag)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>
static_pointer_cast(const shared_ptr<_Tp1> & __r)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>
const_pointer_cast(const shared_ptr<_Tp1> & __r)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>
dynamic_pointer_cast(const shared_ptr<_Tp1> & __r)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:
weak_ptr()1054       weak_ptr()
1055       : __weak_ptr<_Tp>() { }
1056 
1057       template<typename _Tp1>
weak_ptr(const weak_ptr<_Tp1> & __r)1058         weak_ptr(const weak_ptr<_Tp1>& __r)
1059 	: __weak_ptr<_Tp>(__r) { }
1060 
1061       template<typename _Tp1>
weak_ptr(const shared_ptr<_Tp1> & __r)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>
lock()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:
enable_shared_from_this()1108       enable_shared_from_this() { }
1109 
enable_shared_from_this(const enable_shared_from_this &)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 
~enable_shared_from_this()1116       ~enable_shared_from_this() { }
1117 
1118     public:
1119       shared_ptr<_Tp>
shared_from_this()1120       shared_from_this()
1121       { return shared_ptr<_Tp>(this->_M_weak_this); }
1122 
1123       shared_ptr<const _Tp>
shared_from_this()1124       shared_from_this() const
1125       { return shared_ptr<const _Tp>(this->_M_weak_this); }
1126 
1127     private:
1128       template<typename _Tp1>
1129         void
_M_weak_assign(_Tp1 * __p,const __shared_count<> & __n)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
__enable_shared_from_this_helper(const __shared_count<> & __pn,const enable_shared_from_this * __pe,const _Tp1 * __px)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
1150