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-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  */
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>
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
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,
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<>&,
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
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
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
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
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
1498  { return __lhs.owner_before(__rhs); }
1499 
1500  bool
1501  operator()(const _Tp& __lhs, const _Tp1& __rhs) const
1502  { return __lhs.owner_before(__rhs); }
1503 
1504  bool
1505  operator()(const _Tp1& __lhs, const _Tp& __rhs) const
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
Part of RTTI.
Definition: typeinfo:88
Base class for all library exceptions.
Definition: exception:60
The standard allocator, as per [20.4].
Definition: allocator.h:108
complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:386
Scoped lock idiom.
Definition: concurrence.h:231
Non-standard RAII type for managing pointers obtained from allocators.
Definition: allocated_ptr.h:46
A smart pointer with reference-counted copy semantics.
Partial specializations for pointer types.
A simple smart pointer providing strict ownership semantics.
Definition: auto_ptr.h:87
Primary class template for reference_wrapper.
Definition: functional:435
_Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:47
Exception possibly thrown by shared_ptr.
Base class allowing use of member function shared_from_this.
__allocated_ptr< _Alloc > __allocate_guarded(_Alloc &__a)
Allocate space for a single object using __a.
One of the comparison functors.
Definition: stl_function.h:340
void lock(_L1 &__l1, _L2 &__l2, _L3 &...__l3)
Generic lock.
Definition: mutex:540
Uniform interface to all allocator types.
static auto construct(_Alloc &__a, _Tp *__p, _Args &&...__args) -> decltype(_S_construct(__a, __p, std::forward< _Args >(__args)...))
Construct an object of type _Tp.
A smart pointer with weak semantics.
is_void
Definition: type_traits:211
static void destroy(_Alloc &__a, _Tp *__p)
Destroy an object of type _Tp.
20.7.1.2 unique_ptr for single objects.
Definition: unique_ptr.h:116
virtual char const * what() const noexcept
Primary template owner_less.
_Del * get_deleter(const __shared_ptr< _Tp, _Lp > &__p) noexcept
20.7.2.2.10 shared_ptr get_deleter
ISO C++ entities toplevel namespace is std.
Primary class template hash.
Definition: system_error:134
allocator<void> specialization.
Definition: allocator.h:68