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