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