xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/shared_ptr_base.h (revision f3cfa6f6ce31685c6c4a758bc430e69eb99f50a4)
1 // shared_ptr and weak_ptr implementation details -*- C++ -*-
2 
3 // Copyright (C) 2007-2016 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 // GCC Note: Based on files from version 1.32.0 of the Boost library.
26 
27 //  shared_count.hpp
28 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
29 
30 //  shared_ptr.hpp
31 //  Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
32 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
33 
34 //  weak_ptr.hpp
35 //  Copyright (C) 2001, 2002, 2003 Peter Dimov
36 
37 //  enable_shared_from_this.hpp
38 //  Copyright (C) 2002 Peter Dimov
39 
40 // Distributed under the Boost Software License, Version 1.0. (See
41 // accompanying file LICENSE_1_0.txt or copy at
42 // http://www.boost.org/LICENSE_1_0.txt)
43 
44 /** @file bits/shared_ptr_base.h
45  *  This is an internal header file, included by other library headers.
46  *  Do not attempt to use it directly. @headername{memory}
47  */
48 
49 #ifndef _SHARED_PTR_BASE_H
50 #define _SHARED_PTR_BASE_H 1
51 
52 #include <typeinfo>
53 #include <bits/allocated_ptr.h>
54 #include <ext/aligned_buffer.h>
55 
56 namespace std _GLIBCXX_VISIBILITY(default)
57 {
58 _GLIBCXX_BEGIN_NAMESPACE_VERSION
59 
60 #if _GLIBCXX_USE_DEPRECATED
61   template<typename> class auto_ptr;
62 #endif
63 
64  /**
65    *  @brief  Exception possibly thrown by @c shared_ptr.
66    *  @ingroup exceptions
67    */
68   class bad_weak_ptr : public std::exception
69   {
70   public:
71     virtual char const* what() const noexcept;
72 
73     virtual ~bad_weak_ptr() noexcept;
74   };
75 
76   // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
77   inline void
78   __throw_bad_weak_ptr()
79   { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
80 
81   using __gnu_cxx::_Lock_policy;
82   using __gnu_cxx::__default_lock_policy;
83   using __gnu_cxx::_S_single;
84   using __gnu_cxx::_S_mutex;
85   using __gnu_cxx::_S_atomic;
86 
87   // Empty helper class except when the template argument is _S_mutex.
88   template<_Lock_policy _Lp>
89     class _Mutex_base
90     {
91     protected:
92       // The atomic policy uses fully-fenced builtins, single doesn't care.
93       enum { _S_need_barriers = 0 };
94     };
95 
96   template<>
97     class _Mutex_base<_S_mutex>
98     : public __gnu_cxx::__mutex
99     {
100     protected:
101       // This policy is used when atomic builtins are not available.
102       // The replacement atomic operations might not have the necessary
103       // memory barriers.
104       enum { _S_need_barriers = 1 };
105     };
106 
107   template<_Lock_policy _Lp = __default_lock_policy>
108     class _Sp_counted_base
109     : public _Mutex_base<_Lp>
110     {
111     public:
112       _Sp_counted_base() noexcept
113       : _M_use_count(1), _M_weak_count(1) { }
114 
115       virtual
116       ~_Sp_counted_base() noexcept
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() noexcept = 0;
123 
124       // Called when _M_weak_count drops to zero.
125       virtual void
126       _M_destroy() noexcept
127       { delete this; }
128 
129       virtual void*
130       _M_get_deleter(const std::type_info&) noexcept = 0;
131 
132       void
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       bool
140       _M_add_ref_lock_nothrow();
141 
142       void
143       _M_release() noexcept
144       {
145         // Be race-detector-friendly.  For more info see bits/c++config.
146         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
147 	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
148 	  {
149             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
150 	    _M_dispose();
151 	    // There must be a memory barrier between dispose() and destroy()
152 	    // to ensure that the effects of dispose() are observed in the
153 	    // thread that runs destroy().
154 	    // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
155 	    if (_Mutex_base<_Lp>::_S_need_barriers)
156 	      {
157 		__atomic_thread_fence (__ATOMIC_ACQ_REL);
158 	      }
159 
160             // Be race-detector-friendly.  For more info see bits/c++config.
161             _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
162 	    if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
163 						       -1) == 1)
164               {
165                 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
166 	        _M_destroy();
167               }
168 	  }
169       }
170 
171       void
172       _M_weak_add_ref() noexcept
173       { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
174 
175       void
176       _M_weak_release() noexcept
177       {
178         // Be race-detector-friendly. For more info see bits/c++config.
179         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
180 	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
181 	  {
182             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
183 	    if (_Mutex_base<_Lp>::_S_need_barriers)
184 	      {
185 	        // See _M_release(),
186 	        // destroy() must observe results of dispose()
187 		__atomic_thread_fence (__ATOMIC_ACQ_REL);
188 	      }
189 	    _M_destroy();
190 	  }
191       }
192 
193       long
194       _M_get_use_count() const noexcept
195       {
196         // No memory barrier is used here so there is no synchronization
197         // with other threads.
198         return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
199       }
200 
201     private:
202       _Sp_counted_base(_Sp_counted_base const&) = delete;
203       _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
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 (_M_use_count == 0)
215 	__throw_bad_weak_ptr();
216       ++_M_use_count;
217     }
218 
219   template<>
220     inline void
221     _Sp_counted_base<_S_mutex>::
222     _M_add_ref_lock()
223     {
224       __gnu_cxx::__scoped_lock sentry(*this);
225       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
226 	{
227 	  _M_use_count = 0;
228 	  __throw_bad_weak_ptr();
229 	}
230     }
231 
232   template<>
233     inline void
234     _Sp_counted_base<_S_atomic>::
235     _M_add_ref_lock()
236     {
237       // Perform lock-free add-if-not-zero operation.
238       _Atomic_word __count = _M_get_use_count();
239       do
240 	{
241 	  if (__count == 0)
242 	    __throw_bad_weak_ptr();
243 	  // Replace the current counter value with the old value + 1, as
244 	  // long as it's not changed meanwhile.
245 	}
246       while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
247 					  true, __ATOMIC_ACQ_REL,
248 					  __ATOMIC_RELAXED));
249     }
250 
251   template<>
252     inline bool
253     _Sp_counted_base<_S_single>::
254     _M_add_ref_lock_nothrow()
255     {
256       if (_M_use_count == 0)
257 	return false;
258       ++_M_use_count;
259       return true;
260     }
261 
262   template<>
263     inline bool
264     _Sp_counted_base<_S_mutex>::
265     _M_add_ref_lock_nothrow()
266     {
267       __gnu_cxx::__scoped_lock sentry(*this);
268       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
269 	{
270 	  _M_use_count = 0;
271 	  return false;
272 	}
273       return true;
274     }
275 
276   template<>
277     inline bool
278     _Sp_counted_base<_S_atomic>::
279     _M_add_ref_lock_nothrow()
280     {
281       // Perform lock-free add-if-not-zero operation.
282       _Atomic_word __count = _M_get_use_count();
283       do
284 	{
285 	  if (__count == 0)
286 	    return false;
287 	  // Replace the current counter value with the old value + 1, as
288 	  // long as it's not changed meanwhile.
289 	}
290       while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
291 					  true, __ATOMIC_ACQ_REL,
292 					  __ATOMIC_RELAXED));
293       return true;
294     }
295 
296   template<>
297     inline void
298     _Sp_counted_base<_S_single>::_M_add_ref_copy()
299     { ++_M_use_count; }
300 
301   template<>
302     inline void
303     _Sp_counted_base<_S_single>::_M_release() noexcept
304     {
305       if (--_M_use_count == 0)
306         {
307           _M_dispose();
308           if (--_M_weak_count == 0)
309             _M_destroy();
310         }
311     }
312 
313   template<>
314     inline void
315     _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept
316     { ++_M_weak_count; }
317 
318   template<>
319     inline void
320     _Sp_counted_base<_S_single>::_M_weak_release() noexcept
321     {
322       if (--_M_weak_count == 0)
323         _M_destroy();
324     }
325 
326   template<>
327     inline long
328     _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept
329     { return _M_use_count; }
330 
331 
332   // Forward declarations.
333   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
334     class __shared_ptr;
335 
336   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
337     class __weak_ptr;
338 
339   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
340     class __enable_shared_from_this;
341 
342   template<typename _Tp>
343     class shared_ptr;
344 
345   template<typename _Tp>
346     class weak_ptr;
347 
348   template<typename _Tp>
349     struct owner_less;
350 
351   template<typename _Tp>
352     class enable_shared_from_this;
353 
354   template<_Lock_policy _Lp = __default_lock_policy>
355     class __weak_count;
356 
357   template<_Lock_policy _Lp = __default_lock_policy>
358     class __shared_count;
359 
360 
361   // Counted ptr with no deleter or allocator support
362   template<typename _Ptr, _Lock_policy _Lp>
363     class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
364     {
365     public:
366       explicit
367       _Sp_counted_ptr(_Ptr __p) noexcept
368       : _M_ptr(__p) { }
369 
370       virtual void
371       _M_dispose() noexcept
372       { delete _M_ptr; }
373 
374       virtual void
375       _M_destroy() noexcept
376       { delete this; }
377 
378       virtual void*
379       _M_get_deleter(const std::type_info&) noexcept
380       { return nullptr; }
381 
382       _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
383       _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
384 
385     private:
386       _Ptr             _M_ptr;
387     };
388 
389   template<>
390     inline void
391     _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { }
392 
393   template<>
394     inline void
395     _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { }
396 
397   template<>
398     inline void
399     _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { }
400 
401   template<int _Nm, typename _Tp,
402 	   bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
403     struct _Sp_ebo_helper;
404 
405   /// Specialization using EBO.
406   template<int _Nm, typename _Tp>
407     struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp
408     {
409       explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { }
410 
411       static _Tp&
412       _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); }
413     };
414 
415   /// Specialization not using EBO.
416   template<int _Nm, typename _Tp>
417     struct _Sp_ebo_helper<_Nm, _Tp, false>
418     {
419       explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { }
420 
421       static _Tp&
422       _S_get(_Sp_ebo_helper& __eboh)
423       { return __eboh._M_tp; }
424 
425     private:
426       _Tp _M_tp;
427     };
428 
429   // Support for custom deleter and/or allocator
430   template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
431     class _Sp_counted_deleter final : public _Sp_counted_base<_Lp>
432     {
433       class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc>
434       {
435 	typedef _Sp_ebo_helper<0, _Deleter>	_Del_base;
436 	typedef _Sp_ebo_helper<1, _Alloc>	_Alloc_base;
437 
438       public:
439 	_Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
440 	: _M_ptr(__p), _Del_base(__d), _Alloc_base(__a)
441 	{ }
442 
443 	_Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); }
444 	_Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); }
445 
446 	_Ptr _M_ptr;
447       };
448 
449     public:
450       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>;
451 
452       // __d(__p) must not throw.
453       _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
454       : _M_impl(__p, __d, _Alloc()) { }
455 
456       // __d(__p) must not throw.
457       _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
458       : _M_impl(__p, __d, __a) { }
459 
460       ~_Sp_counted_deleter() noexcept { }
461 
462       virtual void
463       _M_dispose() noexcept
464       { _M_impl._M_del()(_M_impl._M_ptr); }
465 
466       virtual void
467       _M_destroy() noexcept
468       {
469 	__allocator_type __a(_M_impl._M_alloc());
470 	__allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
471 	this->~_Sp_counted_deleter();
472       }
473 
474       virtual void*
475       _M_get_deleter(const std::type_info& __ti) noexcept
476       {
477 #if __cpp_rtti
478 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
479 	// 2400. shared_ptr's get_deleter() should use addressof()
480         return __ti == typeid(_Deleter)
481 	  ? std::__addressof(_M_impl._M_del())
482 	  : nullptr;
483 #else
484         return nullptr;
485 #endif
486       }
487 
488     private:
489       _Impl _M_impl;
490     };
491 
492   // helpers for make_shared / allocate_shared
493 
494   struct _Sp_make_shared_tag { };
495 
496   template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
497     class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
498     {
499       class _Impl : _Sp_ebo_helper<0, _Alloc>
500       {
501 	typedef _Sp_ebo_helper<0, _Alloc>	_A_base;
502 
503       public:
504 	explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { }
505 
506 	_Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); }
507 
508 	__gnu_cxx::__aligned_buffer<_Tp> _M_storage;
509       };
510 
511     public:
512       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
513 
514       template<typename... _Args>
515 	_Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
516 	: _M_impl(__a)
517 	{
518 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
519 	  // 2070.  allocate_shared should use allocator_traits<A>::construct
520 	  allocator_traits<_Alloc>::construct(__a, _M_ptr(),
521 	      std::forward<_Args>(__args)...); // might throw
522 	}
523 
524       ~_Sp_counted_ptr_inplace() noexcept { }
525 
526       virtual void
527       _M_dispose() noexcept
528       {
529 	allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
530       }
531 
532       // Override because the allocator needs to know the dynamic type
533       virtual void
534       _M_destroy() noexcept
535       {
536 	__allocator_type __a(_M_impl._M_alloc());
537 	__allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
538 	this->~_Sp_counted_ptr_inplace();
539       }
540 
541       // Sneaky trick so __shared_ptr can get the managed pointer
542       virtual void*
543       _M_get_deleter(const std::type_info& __ti) noexcept
544       {
545 #if __cpp_rtti
546 	if (__ti == typeid(_Sp_make_shared_tag))
547 	  return const_cast<typename remove_cv<_Tp>::type*>(_M_ptr());
548 #endif
549 	return nullptr;
550       }
551 
552     private:
553       _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
554 
555       _Impl _M_impl;
556     };
557 
558 
559   template<_Lock_policy _Lp>
560     class __shared_count
561     {
562     public:
563       constexpr __shared_count() noexcept : _M_pi(0)
564       { }
565 
566       template<typename _Ptr>
567         explicit
568 	__shared_count(_Ptr __p) : _M_pi(0)
569 	{
570 	  __try
571 	    {
572 	      _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
573 	    }
574 	  __catch(...)
575 	    {
576 	      delete __p;
577 	      __throw_exception_again;
578 	    }
579 	}
580 
581       template<typename _Ptr, typename _Deleter>
582 	__shared_count(_Ptr __p, _Deleter __d)
583 	: __shared_count(__p, std::move(__d), allocator<void>())
584 	{ }
585 
586       template<typename _Ptr, typename _Deleter, typename _Alloc>
587 	__shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
588 	{
589 	  typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
590 	  __try
591 	    {
592 	      typename _Sp_cd_type::__allocator_type __a2(__a);
593 	      auto __guard = std::__allocate_guarded(__a2);
594 	      _Sp_cd_type* __mem = __guard.get();
595 	      ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a));
596 	      _M_pi = __mem;
597 	      __guard = nullptr;
598 	    }
599 	  __catch(...)
600 	    {
601 	      __d(__p); // Call _Deleter on __p.
602 	      __throw_exception_again;
603 	    }
604 	}
605 
606       template<typename _Tp, typename _Alloc, typename... _Args>
607 	__shared_count(_Sp_make_shared_tag, _Tp*, const _Alloc& __a,
608 		       _Args&&... __args)
609 	: _M_pi(0)
610 	{
611 	  typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
612 	  typename _Sp_cp_type::__allocator_type __a2(__a);
613 	  auto __guard = std::__allocate_guarded(__a2);
614 	  _Sp_cp_type* __mem = __guard.get();
615 	  ::new (__mem) _Sp_cp_type(std::move(__a),
616 				    std::forward<_Args>(__args)...);
617 	  _M_pi = __mem;
618 	  __guard = nullptr;
619 	}
620 
621 #if _GLIBCXX_USE_DEPRECATED
622       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
623       template<typename _Tp>
624         explicit
625 	__shared_count(std::auto_ptr<_Tp>&& __r);
626 #endif
627 
628       // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
629       template<typename _Tp, typename _Del>
630         explicit
631 	__shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
632 	{
633 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
634 	  // 2415. Inconsistency between unique_ptr and shared_ptr
635 	  if (__r.get() == nullptr)
636 	    return;
637 
638 	  using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
639 	  using _Del2 = typename conditional<is_reference<_Del>::value,
640 	      reference_wrapper<typename remove_reference<_Del>::type>,
641 	      _Del>::type;
642 	  using _Sp_cd_type
643 	    = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
644 	  using _Alloc = allocator<_Sp_cd_type>;
645 	  using _Alloc_traits = allocator_traits<_Alloc>;
646 	  _Alloc __a;
647 	  _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
648 	  _Alloc_traits::construct(__a, __mem, __r.release(),
649 				   __r.get_deleter());  // non-throwing
650 	  _M_pi = __mem;
651 	}
652 
653       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
654       explicit __shared_count(const __weak_count<_Lp>& __r);
655 
656       // Does not throw if __r._M_get_use_count() == 0, caller must check.
657       explicit __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t);
658 
659       ~__shared_count() noexcept
660       {
661 	if (_M_pi != nullptr)
662 	  _M_pi->_M_release();
663       }
664 
665       __shared_count(const __shared_count& __r) noexcept
666       : _M_pi(__r._M_pi)
667       {
668 	if (_M_pi != 0)
669 	  _M_pi->_M_add_ref_copy();
670       }
671 
672       __shared_count&
673       operator=(const __shared_count& __r) noexcept
674       {
675 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
676 	if (__tmp != _M_pi)
677 	  {
678 	    if (__tmp != 0)
679 	      __tmp->_M_add_ref_copy();
680 	    if (_M_pi != 0)
681 	      _M_pi->_M_release();
682 	    _M_pi = __tmp;
683 	  }
684 	return *this;
685       }
686 
687       void
688       _M_swap(__shared_count& __r) noexcept
689       {
690 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
691 	__r._M_pi = _M_pi;
692 	_M_pi = __tmp;
693       }
694 
695       long
696       _M_get_use_count() const noexcept
697       { return _M_pi != 0 ? _M_pi->_M_get_use_count() : 0; }
698 
699       bool
700       _M_unique() const noexcept
701       { return this->_M_get_use_count() == 1; }
702 
703       void*
704       _M_get_deleter(const std::type_info& __ti) const noexcept
705       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; }
706 
707       bool
708       _M_less(const __shared_count& __rhs) const noexcept
709       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
710 
711       bool
712       _M_less(const __weak_count<_Lp>& __rhs) const noexcept
713       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
714 
715       // Friend function injected into enclosing namespace and found by ADL
716       friend inline bool
717       operator==(const __shared_count& __a, const __shared_count& __b) noexcept
718       { return __a._M_pi == __b._M_pi; }
719 
720     private:
721       friend class __weak_count<_Lp>;
722 
723       _Sp_counted_base<_Lp>*  _M_pi;
724     };
725 
726 
727   template<_Lock_policy _Lp>
728     class __weak_count
729     {
730     public:
731       constexpr __weak_count() noexcept : _M_pi(nullptr)
732       { }
733 
734       __weak_count(const __shared_count<_Lp>& __r) noexcept
735       : _M_pi(__r._M_pi)
736       {
737 	if (_M_pi != nullptr)
738 	  _M_pi->_M_weak_add_ref();
739       }
740 
741       __weak_count(const __weak_count& __r) noexcept
742       : _M_pi(__r._M_pi)
743       {
744 	if (_M_pi != nullptr)
745 	  _M_pi->_M_weak_add_ref();
746       }
747 
748       __weak_count(__weak_count&& __r) noexcept
749       : _M_pi(__r._M_pi)
750       { __r._M_pi = nullptr; }
751 
752       ~__weak_count() noexcept
753       {
754 	if (_M_pi != nullptr)
755 	  _M_pi->_M_weak_release();
756       }
757 
758       __weak_count&
759       operator=(const __shared_count<_Lp>& __r) noexcept
760       {
761 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
762 	if (__tmp != nullptr)
763 	  __tmp->_M_weak_add_ref();
764 	if (_M_pi != nullptr)
765 	  _M_pi->_M_weak_release();
766 	_M_pi = __tmp;
767 	return *this;
768       }
769 
770       __weak_count&
771       operator=(const __weak_count& __r) noexcept
772       {
773 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
774 	if (__tmp != nullptr)
775 	  __tmp->_M_weak_add_ref();
776 	if (_M_pi != nullptr)
777 	  _M_pi->_M_weak_release();
778 	_M_pi = __tmp;
779 	return *this;
780       }
781 
782       __weak_count&
783       operator=(__weak_count&& __r) noexcept
784       {
785 	if (_M_pi != nullptr)
786 	  _M_pi->_M_weak_release();
787 	_M_pi = __r._M_pi;
788         __r._M_pi = nullptr;
789 	return *this;
790       }
791 
792       void
793       _M_swap(__weak_count& __r) noexcept
794       {
795 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
796 	__r._M_pi = _M_pi;
797 	_M_pi = __tmp;
798       }
799 
800       long
801       _M_get_use_count() const noexcept
802       { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
803 
804       bool
805       _M_less(const __weak_count& __rhs) const noexcept
806       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
807 
808       bool
809       _M_less(const __shared_count<_Lp>& __rhs) const noexcept
810       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
811 
812       // Friend function injected into enclosing namespace and found by ADL
813       friend inline bool
814       operator==(const __weak_count& __a, const __weak_count& __b) noexcept
815       { return __a._M_pi == __b._M_pi; }
816 
817     private:
818       friend class __shared_count<_Lp>;
819 
820       _Sp_counted_base<_Lp>*  _M_pi;
821     };
822 
823   // Now that __weak_count is defined we can define this constructor:
824   template<_Lock_policy _Lp>
825     inline
826     __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
827     : _M_pi(__r._M_pi)
828     {
829       if (_M_pi != nullptr)
830 	_M_pi->_M_add_ref_lock();
831       else
832 	__throw_bad_weak_ptr();
833     }
834 
835   // Now that __weak_count is defined we can define this constructor:
836   template<_Lock_policy _Lp>
837     inline
838     __shared_count<_Lp>::
839     __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t)
840     : _M_pi(__r._M_pi)
841     {
842       if (_M_pi != nullptr)
843 	if (!_M_pi->_M_add_ref_lock_nothrow())
844 	  _M_pi = nullptr;
845     }
846 
847   // Support for enable_shared_from_this.
848 
849   // Friend of __enable_shared_from_this.
850   template<_Lock_policy _Lp, typename _Tp1, typename _Tp2>
851     void
852     __enable_shared_from_this_helper(const __shared_count<_Lp>&,
853 				     const __enable_shared_from_this<_Tp1,
854 				     _Lp>*, const _Tp2*) noexcept;
855 
856   // Friend of enable_shared_from_this.
857   template<typename _Tp1, typename _Tp2>
858     void
859     __enable_shared_from_this_helper(const __shared_count<>&,
860 				     const enable_shared_from_this<_Tp1>*,
861 				     const _Tp2*) noexcept;
862 
863   template<_Lock_policy _Lp>
864     inline void
865     __enable_shared_from_this_helper(const __shared_count<_Lp>&, ...) noexcept
866     { }
867 
868 
869   template<typename _Tp, _Lock_policy _Lp>
870     class __shared_ptr
871     {
872       template<typename _Ptr>
873 	using _Convertible
874 	  = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type;
875 
876     public:
877       typedef _Tp   element_type;
878 
879       constexpr __shared_ptr() noexcept
880       : _M_ptr(0), _M_refcount()
881       { }
882 
883       template<typename _Tp1>
884 	explicit __shared_ptr(_Tp1* __p)
885         : _M_ptr(__p), _M_refcount(__p)
886 	{
887 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
888 	  static_assert( !is_void<_Tp1>::value, "incomplete type" );
889 	  static_assert( sizeof(_Tp1) > 0, "incomplete type" );
890 	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
891 	}
892 
893       template<typename _Tp1, typename _Deleter>
894 	__shared_ptr(_Tp1* __p, _Deleter __d)
895 	: _M_ptr(__p), _M_refcount(__p, __d)
896 	{
897 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
898 	  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
899 	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
900 	}
901 
902       template<typename _Tp1, typename _Deleter, typename _Alloc>
903 	__shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
904 	: _M_ptr(__p), _M_refcount(__p, __d, std::move(__a))
905 	{
906 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
907 	  // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
908 	  __enable_shared_from_this_helper(_M_refcount, __p, __p);
909 	}
910 
911       template<typename _Deleter>
912 	__shared_ptr(nullptr_t __p, _Deleter __d)
913 	: _M_ptr(0), _M_refcount(__p, __d)
914 	{ }
915 
916       template<typename _Deleter, typename _Alloc>
917         __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
918 	: _M_ptr(0), _M_refcount(__p, __d, std::move(__a))
919 	{ }
920 
921       template<typename _Tp1>
922 	__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept
923 	: _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
924 	{ }
925 
926       __shared_ptr(const __shared_ptr&) noexcept = default;
927       __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
928       ~__shared_ptr() = default;
929 
930       template<typename _Tp1, typename = _Convertible<_Tp1*>>
931 	__shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
932 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
933 	{ }
934 
935       __shared_ptr(__shared_ptr&& __r) noexcept
936       : _M_ptr(__r._M_ptr), _M_refcount()
937       {
938 	_M_refcount._M_swap(__r._M_refcount);
939 	__r._M_ptr = 0;
940       }
941 
942       template<typename _Tp1, typename = _Convertible<_Tp1*>>
943 	__shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
944 	: _M_ptr(__r._M_ptr), _M_refcount()
945 	{
946 	  _M_refcount._M_swap(__r._M_refcount);
947 	  __r._M_ptr = 0;
948 	}
949 
950       template<typename _Tp1>
951 	explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
952 	: _M_refcount(__r._M_refcount) // may throw
953 	{
954 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
955 
956 	  // It is now safe to copy __r._M_ptr, as
957 	  // _M_refcount(__r._M_refcount) did not throw.
958 	  _M_ptr = __r._M_ptr;
959 	}
960 
961       // If an exception is thrown this constructor has no effect.
962       template<typename _Tp1, typename _Del, typename
963 	       = _Convertible<typename unique_ptr<_Tp1, _Del>::pointer>>
964 	__shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
965 	: _M_ptr(__r.get()), _M_refcount()
966 	{
967 	  __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
968 	  auto __raw = _S_raw_ptr(__r.get());
969 	  _M_refcount = __shared_count<_Lp>(std::move(__r));
970 	  __enable_shared_from_this_helper(_M_refcount, __raw, __raw);
971 	}
972 
973 #if _GLIBCXX_USE_DEPRECATED
974       // Postcondition: use_count() == 1 and __r.get() == 0
975       template<typename _Tp1>
976 	__shared_ptr(std::auto_ptr<_Tp1>&& __r);
977 #endif
978 
979       constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
980 
981       template<typename _Tp1>
982 	__shared_ptr&
983 	operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
984 	{
985 	  _M_ptr = __r._M_ptr;
986 	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
987 	  return *this;
988 	}
989 
990 #if _GLIBCXX_USE_DEPRECATED
991       template<typename _Tp1>
992 	__shared_ptr&
993 	operator=(std::auto_ptr<_Tp1>&& __r)
994 	{
995 	  __shared_ptr(std::move(__r)).swap(*this);
996 	  return *this;
997 	}
998 #endif
999 
1000       __shared_ptr&
1001       operator=(__shared_ptr&& __r) noexcept
1002       {
1003 	__shared_ptr(std::move(__r)).swap(*this);
1004 	return *this;
1005       }
1006 
1007       template<class _Tp1>
1008 	__shared_ptr&
1009 	operator=(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
1010 	{
1011 	  __shared_ptr(std::move(__r)).swap(*this);
1012 	  return *this;
1013 	}
1014 
1015       template<typename _Tp1, typename _Del>
1016 	__shared_ptr&
1017 	operator=(std::unique_ptr<_Tp1, _Del>&& __r)
1018 	{
1019 	  __shared_ptr(std::move(__r)).swap(*this);
1020 	  return *this;
1021 	}
1022 
1023       void
1024       reset() noexcept
1025       { __shared_ptr().swap(*this); }
1026 
1027       template<typename _Tp1>
1028 	void
1029 	reset(_Tp1* __p) // _Tp1 must be complete.
1030 	{
1031 	  // Catch self-reset errors.
1032 	  __glibcxx_assert(__p == 0 || __p != _M_ptr);
1033 	  __shared_ptr(__p).swap(*this);
1034 	}
1035 
1036       template<typename _Tp1, typename _Deleter>
1037 	void
1038 	reset(_Tp1* __p, _Deleter __d)
1039 	{ __shared_ptr(__p, __d).swap(*this); }
1040 
1041       template<typename _Tp1, typename _Deleter, typename _Alloc>
1042 	void
1043         reset(_Tp1* __p, _Deleter __d, _Alloc __a)
1044         { __shared_ptr(__p, __d, std::move(__a)).swap(*this); }
1045 
1046       // Allow class instantiation when _Tp is [cv-qual] void.
1047       typename std::add_lvalue_reference<_Tp>::type
1048       operator*() const noexcept
1049       {
1050 	__glibcxx_assert(_M_ptr != 0);
1051 	return *_M_ptr;
1052       }
1053 
1054       _Tp*
1055       operator->() const noexcept
1056       {
1057 	_GLIBCXX_DEBUG_PEDASSERT(_M_ptr != 0);
1058 	return _M_ptr;
1059       }
1060 
1061       _Tp*
1062       get() const noexcept
1063       { return _M_ptr; }
1064 
1065       explicit operator bool() const // never throws
1066       { return _M_ptr == 0 ? false : true; }
1067 
1068       bool
1069       unique() const noexcept
1070       { return _M_refcount._M_unique(); }
1071 
1072       long
1073       use_count() const noexcept
1074       { return _M_refcount._M_get_use_count(); }
1075 
1076       void
1077       swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
1078       {
1079 	std::swap(_M_ptr, __other._M_ptr);
1080 	_M_refcount._M_swap(__other._M_refcount);
1081       }
1082 
1083       template<typename _Tp1>
1084 	bool
1085 	owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1086 	{ return _M_refcount._M_less(__rhs._M_refcount); }
1087 
1088       template<typename _Tp1>
1089 	bool
1090 	owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1091 	{ return _M_refcount._M_less(__rhs._M_refcount); }
1092 
1093 #if __cpp_rtti
1094     protected:
1095       // This constructor is non-standard, it is used by allocate_shared.
1096       template<typename _Alloc, typename... _Args>
1097 	__shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
1098 		     _Args&&... __args)
1099 	: _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
1100 				std::forward<_Args>(__args)...)
1101 	{
1102 	  // _M_ptr needs to point to the newly constructed object.
1103 	  // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
1104 	  void* __p = _M_refcount._M_get_deleter(typeid(__tag));
1105 	  _M_ptr = static_cast<_Tp*>(__p);
1106 	  __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
1107 	}
1108 #else
1109       template<typename _Alloc>
1110         struct _Deleter
1111         {
1112           void operator()(typename _Alloc::value_type* __ptr)
1113           {
1114 	    __allocated_ptr<_Alloc> __guard{ _M_alloc, __ptr };
1115 	    allocator_traits<_Alloc>::destroy(_M_alloc, __guard.get());
1116           }
1117           _Alloc _M_alloc;
1118         };
1119 
1120       template<typename _Alloc, typename... _Args>
1121 	__shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
1122 		     _Args&&... __args)
1123 	: _M_ptr(), _M_refcount()
1124 	{
1125 	  typedef typename allocator_traits<_Alloc>::template
1126 	    rebind_traits<typename std::remove_cv<_Tp>::type> __traits;
1127 	  _Deleter<typename __traits::allocator_type> __del = { __a };
1128 	  auto __guard = std::__allocate_guarded(__del._M_alloc);
1129 	  auto __ptr = __guard.get();
1130 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1131 	  // 2070. allocate_shared should use allocator_traits<A>::construct
1132 	  __traits::construct(__del._M_alloc, __ptr,
1133 			      std::forward<_Args>(__args)...);
1134 	  __guard = nullptr;
1135 	  __shared_count<_Lp> __count(__ptr, __del, __del._M_alloc);
1136 	  _M_refcount._M_swap(__count);
1137 	  _M_ptr = __ptr;
1138 	  __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
1139 	}
1140 #endif
1141 
1142       template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
1143 	       typename... _Args>
1144 	friend __shared_ptr<_Tp1, _Lp1>
1145 	__allocate_shared(const _Alloc& __a, _Args&&... __args);
1146 
1147       // This constructor is used by __weak_ptr::lock() and
1148       // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
1149       __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t)
1150       : _M_refcount(__r._M_refcount, std::nothrow)
1151       {
1152 	_M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr;
1153       }
1154 
1155       friend class __weak_ptr<_Tp, _Lp>;
1156 
1157     private:
1158       void*
1159       _M_get_deleter(const std::type_info& __ti) const noexcept
1160       { return _M_refcount._M_get_deleter(__ti); }
1161 
1162       template<typename _Tp1>
1163 	static _Tp1*
1164 	_S_raw_ptr(_Tp1* __ptr)
1165 	{ return __ptr; }
1166 
1167       template<typename _Tp1>
1168 	static auto
1169 	_S_raw_ptr(_Tp1 __ptr) -> decltype(std::__addressof(*__ptr))
1170 	{ return std::__addressof(*__ptr); }
1171 
1172       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1173       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1174 
1175       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
1176 	friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
1177 
1178       _Tp*	   	   _M_ptr;         // Contained pointer.
1179       __shared_count<_Lp>  _M_refcount;    // Reference counter.
1180     };
1181 
1182 
1183   // 20.7.2.2.7 shared_ptr comparisons
1184   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1185     inline bool
1186     operator==(const __shared_ptr<_Tp1, _Lp>& __a,
1187 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1188     { return __a.get() == __b.get(); }
1189 
1190   template<typename _Tp, _Lock_policy _Lp>
1191     inline bool
1192     operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1193     { return !__a; }
1194 
1195   template<typename _Tp, _Lock_policy _Lp>
1196     inline bool
1197     operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1198     { return !__a; }
1199 
1200   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1201     inline bool
1202     operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
1203 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1204     { return __a.get() != __b.get(); }
1205 
1206   template<typename _Tp, _Lock_policy _Lp>
1207     inline bool
1208     operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1209     { return (bool)__a; }
1210 
1211   template<typename _Tp, _Lock_policy _Lp>
1212     inline bool
1213     operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1214     { return (bool)__a; }
1215 
1216   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1217     inline bool
1218     operator<(const __shared_ptr<_Tp1, _Lp>& __a,
1219 	      const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1220     {
1221       typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
1222       return std::less<_CT>()(__a.get(), __b.get());
1223     }
1224 
1225   template<typename _Tp, _Lock_policy _Lp>
1226     inline bool
1227     operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1228     { return std::less<_Tp*>()(__a.get(), nullptr); }
1229 
1230   template<typename _Tp, _Lock_policy _Lp>
1231     inline bool
1232     operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1233     { return std::less<_Tp*>()(nullptr, __a.get()); }
1234 
1235   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1236     inline bool
1237     operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
1238 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1239     { return !(__b < __a); }
1240 
1241   template<typename _Tp, _Lock_policy _Lp>
1242     inline bool
1243     operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1244     { return !(nullptr < __a); }
1245 
1246   template<typename _Tp, _Lock_policy _Lp>
1247     inline bool
1248     operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1249     { return !(__a < nullptr); }
1250 
1251   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1252     inline bool
1253     operator>(const __shared_ptr<_Tp1, _Lp>& __a,
1254 	      const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1255     { return (__b < __a); }
1256 
1257   template<typename _Tp, _Lock_policy _Lp>
1258     inline bool
1259     operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1260     { return std::less<_Tp*>()(nullptr, __a.get()); }
1261 
1262   template<typename _Tp, _Lock_policy _Lp>
1263     inline bool
1264     operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1265     { return std::less<_Tp*>()(__a.get(), nullptr); }
1266 
1267   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1268     inline bool
1269     operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
1270 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1271     { return !(__a < __b); }
1272 
1273   template<typename _Tp, _Lock_policy _Lp>
1274     inline bool
1275     operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1276     { return !(__a < nullptr); }
1277 
1278   template<typename _Tp, _Lock_policy _Lp>
1279     inline bool
1280     operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1281     { return !(nullptr < __a); }
1282 
1283   template<typename _Sp>
1284     struct _Sp_less : public binary_function<_Sp, _Sp, bool>
1285     {
1286       bool
1287       operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept
1288       {
1289 	typedef typename _Sp::element_type element_type;
1290 	return std::less<element_type*>()(__lhs.get(), __rhs.get());
1291       }
1292     };
1293 
1294   template<typename _Tp, _Lock_policy _Lp>
1295     struct less<__shared_ptr<_Tp, _Lp>>
1296     : public _Sp_less<__shared_ptr<_Tp, _Lp>>
1297     { };
1298 
1299   // 20.7.2.2.8 shared_ptr specialized algorithms.
1300   template<typename _Tp, _Lock_policy _Lp>
1301     inline void
1302     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
1303     { __a.swap(__b); }
1304 
1305   // 20.7.2.2.9 shared_ptr casts
1306 
1307   // The seemingly equivalent code:
1308   // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
1309   // will eventually result in undefined behaviour, attempting to
1310   // delete the same object twice.
1311   /// static_pointer_cast
1312   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1313     inline __shared_ptr<_Tp, _Lp>
1314     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1315     { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
1316 
1317   // The seemingly equivalent code:
1318   // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
1319   // will eventually result in undefined behaviour, attempting to
1320   // delete the same object twice.
1321   /// const_pointer_cast
1322   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1323     inline __shared_ptr<_Tp, _Lp>
1324     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1325     { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
1326 
1327   // The seemingly equivalent code:
1328   // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
1329   // will eventually result in undefined behaviour, attempting to
1330   // delete the same object twice.
1331   /// dynamic_pointer_cast
1332   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1333     inline __shared_ptr<_Tp, _Lp>
1334     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1335     {
1336       if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
1337 	return __shared_ptr<_Tp, _Lp>(__r, __p);
1338       return __shared_ptr<_Tp, _Lp>();
1339     }
1340 
1341 
1342   template<typename _Tp, _Lock_policy _Lp>
1343     class __weak_ptr
1344     {
1345       template<typename _Ptr>
1346 	using _Convertible
1347 	  = typename enable_if<is_convertible<_Ptr, _Tp*>::value>::type;
1348 
1349     public:
1350       typedef _Tp element_type;
1351 
1352       constexpr __weak_ptr() noexcept
1353       : _M_ptr(nullptr), _M_refcount()
1354       { }
1355 
1356       __weak_ptr(const __weak_ptr&) noexcept = default;
1357 
1358       ~__weak_ptr() = default;
1359 
1360       // The "obvious" converting constructor implementation:
1361       //
1362       //  template<typename _Tp1>
1363       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
1364       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
1365       //    { }
1366       //
1367       // has a serious problem.
1368       //
1369       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
1370       //  conversion may require access to *__r._M_ptr (virtual inheritance).
1371       //
1372       // It is not possible to avoid spurious access violations since
1373       // in multithreaded programs __r._M_ptr may be invalidated at any point.
1374       template<typename _Tp1, typename = _Convertible<_Tp1*>>
1375 	__weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
1376 	: _M_refcount(__r._M_refcount)
1377         { _M_ptr = __r.lock().get(); }
1378 
1379       template<typename _Tp1, typename = _Convertible<_Tp1*>>
1380 	__weak_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1381 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1382 	{ }
1383 
1384       __weak_ptr(__weak_ptr&& __r) noexcept
1385       : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
1386       { __r._M_ptr = nullptr; }
1387 
1388       template<typename _Tp1, typename = _Convertible<_Tp1*>>
1389 	__weak_ptr(__weak_ptr<_Tp1, _Lp>&& __r) noexcept
1390 	: _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount))
1391         { __r._M_ptr = nullptr; }
1392 
1393       __weak_ptr&
1394       operator=(const __weak_ptr& __r) noexcept = default;
1395 
1396       template<typename _Tp1>
1397 	__weak_ptr&
1398 	operator=(const __weak_ptr<_Tp1, _Lp>& __r) noexcept
1399 	{
1400 	  _M_ptr = __r.lock().get();
1401 	  _M_refcount = __r._M_refcount;
1402 	  return *this;
1403 	}
1404 
1405       template<typename _Tp1>
1406 	__weak_ptr&
1407 	operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1408 	{
1409 	  _M_ptr = __r._M_ptr;
1410 	  _M_refcount = __r._M_refcount;
1411 	  return *this;
1412 	}
1413 
1414       __weak_ptr&
1415       operator=(__weak_ptr&& __r) noexcept
1416       {
1417 	_M_ptr = __r._M_ptr;
1418 	_M_refcount = std::move(__r._M_refcount);
1419 	__r._M_ptr = nullptr;
1420 	return *this;
1421       }
1422 
1423       template<typename _Tp1>
1424 	__weak_ptr&
1425 	operator=(__weak_ptr<_Tp1, _Lp>&& __r) noexcept
1426 	{
1427 	  _M_ptr = __r.lock().get();
1428 	  _M_refcount = std::move(__r._M_refcount);
1429 	  __r._M_ptr = nullptr;
1430 	  return *this;
1431 	}
1432 
1433       __shared_ptr<_Tp, _Lp>
1434       lock() const noexcept
1435       { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); }
1436 
1437       long
1438       use_count() const noexcept
1439       { return _M_refcount._M_get_use_count(); }
1440 
1441       bool
1442       expired() const noexcept
1443       { return _M_refcount._M_get_use_count() == 0; }
1444 
1445       template<typename _Tp1>
1446 	bool
1447 	owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept
1448 	{ return _M_refcount._M_less(__rhs._M_refcount); }
1449 
1450       template<typename _Tp1>
1451 	bool
1452 	owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept
1453 	{ return _M_refcount._M_less(__rhs._M_refcount); }
1454 
1455       void
1456       reset() noexcept
1457       { __weak_ptr().swap(*this); }
1458 
1459       void
1460       swap(__weak_ptr& __s) noexcept
1461       {
1462 	std::swap(_M_ptr, __s._M_ptr);
1463 	_M_refcount._M_swap(__s._M_refcount);
1464       }
1465 
1466     private:
1467       // Used by __enable_shared_from_this.
1468       void
1469       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
1470       {
1471 	if (use_count() == 0)
1472 	  {
1473 	    _M_ptr = __ptr;
1474 	    _M_refcount = __refcount;
1475 	  }
1476       }
1477 
1478       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1479       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1480       friend class __enable_shared_from_this<_Tp, _Lp>;
1481       friend class enable_shared_from_this<_Tp>;
1482 
1483       _Tp*	 	 _M_ptr;         // Contained pointer.
1484       __weak_count<_Lp>  _M_refcount;    // Reference counter.
1485     };
1486 
1487   // 20.7.2.3.6 weak_ptr specialized algorithms.
1488   template<typename _Tp, _Lock_policy _Lp>
1489     inline void
1490     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
1491     { __a.swap(__b); }
1492 
1493   template<typename _Tp, typename _Tp1>
1494     struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
1495     {
1496       bool
1497       operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept
1498       { return __lhs.owner_before(__rhs); }
1499 
1500       bool
1501       operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept
1502       { return __lhs.owner_before(__rhs); }
1503 
1504       bool
1505       operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept
1506       { return __lhs.owner_before(__rhs); }
1507     };
1508 
1509   template<typename _Tp, _Lock_policy _Lp>
1510     struct owner_less<__shared_ptr<_Tp, _Lp>>
1511     : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
1512     { };
1513 
1514   template<typename _Tp, _Lock_policy _Lp>
1515     struct owner_less<__weak_ptr<_Tp, _Lp>>
1516     : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
1517     { };
1518 
1519 
1520   template<typename _Tp, _Lock_policy _Lp>
1521     class __enable_shared_from_this
1522     {
1523     protected:
1524       constexpr __enable_shared_from_this() noexcept { }
1525 
1526       __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
1527 
1528       __enable_shared_from_this&
1529       operator=(const __enable_shared_from_this&) noexcept
1530       { return *this; }
1531 
1532       ~__enable_shared_from_this() { }
1533 
1534     public:
1535       __shared_ptr<_Tp, _Lp>
1536       shared_from_this()
1537       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
1538 
1539       __shared_ptr<const _Tp, _Lp>
1540       shared_from_this() const
1541       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
1542 
1543     private:
1544       template<typename _Tp1>
1545 	void
1546 	_M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
1547 	{ _M_weak_this._M_assign(__p, __n); }
1548 
1549       template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2>
1550 	friend void
1551 	__enable_shared_from_this_helper(const __shared_count<_Lp1>&,
1552 					 const __enable_shared_from_this<_Tp1,
1553 					 _Lp1>*, const _Tp2*) noexcept;
1554 
1555       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
1556     };
1557 
1558   template<_Lock_policy _Lp1, typename _Tp1, typename _Tp2>
1559     inline void
1560     __enable_shared_from_this_helper(const __shared_count<_Lp1>& __pn,
1561 				     const __enable_shared_from_this<_Tp1,
1562 				     _Lp1>* __pe,
1563 				     const _Tp2* __px) noexcept
1564     {
1565       if (__pe != nullptr)
1566 	__pe->_M_weak_assign(const_cast<_Tp2*>(__px), __pn);
1567     }
1568 
1569   template<typename _Tp, _Lock_policy _Lp, typename _Alloc, typename... _Args>
1570     inline __shared_ptr<_Tp, _Lp>
1571     __allocate_shared(const _Alloc& __a, _Args&&... __args)
1572     {
1573       return __shared_ptr<_Tp, _Lp>(_Sp_make_shared_tag(), __a,
1574 				    std::forward<_Args>(__args)...);
1575     }
1576 
1577   template<typename _Tp, _Lock_policy _Lp, typename... _Args>
1578     inline __shared_ptr<_Tp, _Lp>
1579     __make_shared(_Args&&... __args)
1580     {
1581       typedef typename std::remove_const<_Tp>::type _Tp_nc;
1582       return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
1583 					      std::forward<_Args>(__args)...);
1584     }
1585 
1586   /// std::hash specialization for __shared_ptr.
1587   template<typename _Tp, _Lock_policy _Lp>
1588     struct hash<__shared_ptr<_Tp, _Lp>>
1589     : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
1590     {
1591       size_t
1592       operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
1593       { return std::hash<_Tp*>()(__s.get()); }
1594     };
1595 
1596 _GLIBCXX_END_NAMESPACE_VERSION
1597 } // namespace
1598 
1599 #endif // _SHARED_PTR_BASE_H
1600