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