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