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