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