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-2021 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 // GCC Note: Based on files from version 1.32.0 of the Boost library.
26 
27 // shared_count.hpp
28 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
29 
30 // shared_ptr.hpp
31 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
32 // Copyright (C) 2001, 2002, 2003 Peter Dimov
33 
34 // weak_ptr.hpp
35 // Copyright (C) 2001, 2002, 2003 Peter Dimov
36 
37 // enable_shared_from_this.hpp
38 // Copyright (C) 2002 Peter Dimov
39 
40 // Distributed under the Boost Software License, Version 1.0. (See
41 // accompanying file LICENSE_1_0.txt or copy at
42 // http://www.boost.org/LICENSE_1_0.txt)
43 
44 /** @file bits/shared_ptr_base.h
45  * This is an internal header file, included by other library headers.
46  * Do not attempt to use it directly. @headername{memory}
47  */
48 
49 #ifndef _SHARED_PTR_BASE_H
50 #define _SHARED_PTR_BASE_H 1
51 
52 #include <typeinfo>
53 #include <bits/allocated_ptr.h>
54 #include <bits/allocator.h>
55 #include <bits/exception_defines.h>
56 #include <bits/functional_hash.h>
57 #include <bits/refwrap.h>
58 #include <bits/stl_function.h> // std::less
59 #include <bits/unique_ptr.h>
60 #include <ext/aligned_buffer.h>
61 #include <ext/atomicity.h>
62 #include <ext/concurrence.h>
63 #if __cplusplus > 201703L
64 # include <compare>
65 #endif
66 
67 namespace std _GLIBCXX_VISIBILITY(default)
68 {
69 _GLIBCXX_BEGIN_NAMESPACE_VERSION
70 
71 #if _GLIBCXX_USE_DEPRECATED
72 #pragma GCC diagnostic push
73 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
74  template<typename> class auto_ptr;
75 #pragma GCC diagnostic pop
76 #endif
77 
78  /**
79  * @brief Exception possibly thrown by @c shared_ptr.
80  * @ingroup exceptions
81  */
83  {
84  public:
85  virtual char const* what() const noexcept;
86 
87  virtual ~bad_weak_ptr() noexcept;
88  };
89 
90  // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
91  inline void
92  __throw_bad_weak_ptr()
93  { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
94 
95  using __gnu_cxx::_Lock_policy;
96  using __gnu_cxx::__default_lock_policy;
97  using __gnu_cxx::_S_single;
98  using __gnu_cxx::_S_mutex;
99  using __gnu_cxx::_S_atomic;
100 
101  // Empty helper class except when the template argument is _S_mutex.
102  template<_Lock_policy _Lp>
103  class _Mutex_base
104  {
105  protected:
106  // The atomic policy uses fully-fenced builtins, single doesn't care.
107  enum { _S_need_barriers = 0 };
108  };
109 
110  template<>
111  class _Mutex_base<_S_mutex>
112  : public __gnu_cxx::__mutex
113  {
114  protected:
115  // This policy is used when atomic builtins are not available.
116  // The replacement atomic operations might not have the necessary
117  // memory barriers.
118  enum { _S_need_barriers = 1 };
119  };
120 
121  template<_Lock_policy _Lp = __default_lock_policy>
122  class _Sp_counted_base
123  : public _Mutex_base<_Lp>
124  {
125  public:
126  _Sp_counted_base() noexcept
127  : _M_use_count(1), _M_weak_count(1) { }
128 
129  virtual
130  ~_Sp_counted_base() noexcept
131  { }
132 
133  // Called when _M_use_count drops to zero, to release the resources
134  // managed by *this.
135  virtual void
136  _M_dispose() noexcept = 0;
137 
138  // Called when _M_weak_count drops to zero.
139  virtual void
140  _M_destroy() noexcept
141  { delete this; }
142 
143  virtual void*
144  _M_get_deleter(const std::type_info&) noexcept = 0;
145 
146  void
147  _M_add_ref_copy()
148  { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
149 
150  void
151  _M_add_ref_lock()
152  {
153  if (!_M_add_ref_lock_nothrow())
154  __throw_bad_weak_ptr();
155  }
156 
157  bool
158  _M_add_ref_lock_nothrow() noexcept;
159 
160  void
161  _M_release() noexcept
162  {
163  // Be race-detector-friendly. For more info see bits/c++config.
164  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
165  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
166  {
167  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
168  _M_dispose();
169  // There must be a memory barrier between dispose() and destroy()
170  // to ensure that the effects of dispose() are observed in the
171  // thread that runs destroy().
172  // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
173  if (_Mutex_base<_Lp>::_S_need_barriers)
174  {
175  __atomic_thread_fence (__ATOMIC_ACQ_REL);
176  }
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,
181  -1) == 1)
182  {
183  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
184  _M_destroy();
185  }
186  }
187  }
188 
189  void
190  _M_weak_add_ref() noexcept
191  { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
192 
193  void
194  _M_weak_release() noexcept
195  {
196  // Be race-detector-friendly. For more info see bits/c++config.
197  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
198  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
199  {
200  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
201  if (_Mutex_base<_Lp>::_S_need_barriers)
202  {
203  // See _M_release(),
204  // destroy() must observe results of dispose()
205  __atomic_thread_fence (__ATOMIC_ACQ_REL);
206  }
207  _M_destroy();
208  }
209  }
210 
211  long
212  _M_get_use_count() const noexcept
213  {
214  // No memory barrier is used here so there is no synchronization
215  // with other threads.
216  return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
217  }
218 
219  private:
220  _Sp_counted_base(_Sp_counted_base const&) = delete;
221  _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
222 
223  _Atomic_word _M_use_count; // #shared
224  _Atomic_word _M_weak_count; // #weak + (#shared != 0)
225  };
226 
227  template<>
228  inline bool
229  _Sp_counted_base<_S_single>::
230  _M_add_ref_lock_nothrow() noexcept
231  {
232  if (_M_use_count == 0)
233  return false;
234  ++_M_use_count;
235  return true;
236  }
237 
238  template<>
239  inline bool
240  _Sp_counted_base<_S_mutex>::
241  _M_add_ref_lock_nothrow() noexcept
242  {
243  __gnu_cxx::__scoped_lock sentry(*this);
244  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
245  {
246  _M_use_count = 0;
247  return false;
248  }
249  return true;
250  }
251 
252  template<>
253  inline bool
254  _Sp_counted_base<_S_atomic>::
255  _M_add_ref_lock_nothrow() noexcept
256  {
257  // Perform lock-free add-if-not-zero operation.
258  _Atomic_word __count = _M_get_use_count();
259  do
260  {
261  if (__count == 0)
262  return false;
263  // Replace the current counter value with the old value + 1, as
264  // long as it's not changed meanwhile.
265  }
266  while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
267  true, __ATOMIC_ACQ_REL,
268  __ATOMIC_RELAXED));
269  return true;
270  }
271 
272  template<>
273  inline void
274  _Sp_counted_base<_S_single>::_M_add_ref_copy()
275  { ++_M_use_count; }
276 
277  template<>
278  inline void
279  _Sp_counted_base<_S_single>::_M_release() noexcept
280  {
281  if (--_M_use_count == 0)
282  {
283  _M_dispose();
284  if (--_M_weak_count == 0)
285  _M_destroy();
286  }
287  }
288 
289  template<>
290  inline void
291  _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept
292  { ++_M_weak_count; }
293 
294  template<>
295  inline void
296  _Sp_counted_base<_S_single>::_M_weak_release() noexcept
297  {
298  if (--_M_weak_count == 0)
299  _M_destroy();
300  }
301 
302  template<>
303  inline long
304  _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept
305  { return _M_use_count; }
306 
307 
308  // Forward declarations.
309  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
310  class __shared_ptr;
311 
312  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
313  class __weak_ptr;
314 
315  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
316  class __enable_shared_from_this;
317 
318  template<typename _Tp>
319  class shared_ptr;
320 
321  template<typename _Tp>
322  class weak_ptr;
323 
324  template<typename _Tp>
325  struct owner_less;
326 
327  template<typename _Tp>
328  class enable_shared_from_this;
329 
330  template<_Lock_policy _Lp = __default_lock_policy>
331  class __weak_count;
332 
333  template<_Lock_policy _Lp = __default_lock_policy>
334  class __shared_count;
335 
336 
337  // Counted ptr with no deleter or allocator support
338  template<typename _Ptr, _Lock_policy _Lp>
339  class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
340  {
341  public:
342  explicit
343  _Sp_counted_ptr(_Ptr __p) noexcept
344  : _M_ptr(__p) { }
345 
346  virtual void
347  _M_dispose() noexcept
348  { delete _M_ptr; }
349 
350  virtual void
351  _M_destroy() noexcept
352  { delete this; }
353 
354  virtual void*
355  _M_get_deleter(const std::type_info&) noexcept
356  { return nullptr; }
357 
358  _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
359  _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
360 
361  private:
362  _Ptr _M_ptr;
363  };
364 
365  template<>
366  inline void
367  _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { }
368 
369  template<>
370  inline void
371  _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { }
372 
373  template<>
374  inline void
375  _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { }
376 
377  template<int _Nm, typename _Tp,
378  bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
379  struct _Sp_ebo_helper;
380 
381  /// Specialization using EBO.
382  template<int _Nm, typename _Tp>
383  struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp
384  {
385  explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { }
386  explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { }
387 
388  static _Tp&
389  _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); }
390  };
391 
392  /// Specialization not using EBO.
393  template<int _Nm, typename _Tp>
394  struct _Sp_ebo_helper<_Nm, _Tp, false>
395  {
396  explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { }
397  explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(std::move(__tp)) { }
398 
399  static _Tp&
400  _S_get(_Sp_ebo_helper& __eboh)
401  { return __eboh._M_tp; }
402 
403  private:
404  _Tp _M_tp;
405  };
406 
407  // Support for custom deleter and/or allocator
408  template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
409  class _Sp_counted_deleter final : public _Sp_counted_base<_Lp>
410  {
411  class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc>
412  {
413  typedef _Sp_ebo_helper<0, _Deleter> _Del_base;
414  typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base;
415 
416  public:
417  _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
418  : _Del_base(std::move(__d)), _Alloc_base(__a), _M_ptr(__p)
419  { }
420 
421  _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); }
422  _Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); }
423 
424  _Ptr _M_ptr;
425  };
426 
427  public:
428  using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>;
429 
430  // __d(__p) must not throw.
431  _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
432  : _M_impl(__p, std::move(__d), _Alloc()) { }
433 
434  // __d(__p) must not throw.
435  _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
436  : _M_impl(__p, std::move(__d), __a) { }
437 
438  ~_Sp_counted_deleter() noexcept { }
439 
440  virtual void
441  _M_dispose() noexcept
442  { _M_impl._M_del()(_M_impl._M_ptr); }
443 
444  virtual void
445  _M_destroy() noexcept
446  {
447  __allocator_type __a(_M_impl._M_alloc());
448  __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
449  this->~_Sp_counted_deleter();
450  }
451 
452  virtual void*
453  _M_get_deleter(const type_info& __ti [[__gnu__::__unused__]]) noexcept
454  {
455 #if __cpp_rtti
456  // _GLIBCXX_RESOLVE_LIB_DEFECTS
457  // 2400. shared_ptr's get_deleter() should use addressof()
458  return __ti == typeid(_Deleter)
459  ? std::__addressof(_M_impl._M_del())
460  : nullptr;
461 #else
462  return nullptr;
463 #endif
464  }
465 
466  private:
467  _Impl _M_impl;
468  };
469 
470  // helpers for make_shared / allocate_shared
471 
472  struct _Sp_make_shared_tag
473  {
474  private:
475  template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
476  friend class _Sp_counted_ptr_inplace;
477 
478  static const type_info&
479  _S_ti() noexcept _GLIBCXX_VISIBILITY(default)
480  {
481  alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { };
482  return reinterpret_cast<const type_info&>(__tag);
483  }
484 
485  static bool _S_eq(const type_info&) noexcept;
486  };
487 
488  template<typename _Alloc>
489  struct _Sp_alloc_shared_tag
490  {
491  const _Alloc& _M_a;
492  };
493 
494  template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
495  class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
496  {
497  class _Impl : _Sp_ebo_helper<0, _Alloc>
498  {
499  typedef _Sp_ebo_helper<0, _Alloc> _A_base;
500 
501  public:
502  explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { }
503 
504  _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); }
505 
506  __gnu_cxx::__aligned_buffer<_Tp> _M_storage;
507  };
508 
509  public:
510  using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
511 
512  // Alloc parameter is not a reference so doesn't alias anything in __args
513  template<typename... _Args>
514  _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
515  : _M_impl(__a)
516  {
517  // _GLIBCXX_RESOLVE_LIB_DEFECTS
518  // 2070. allocate_shared should use allocator_traits<A>::construct
520  std::forward<_Args>(__args)...); // might throw
521  }
522 
523  ~_Sp_counted_ptr_inplace() noexcept { }
524 
525  virtual void
526  _M_dispose() noexcept
527  {
528  allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
529  }
530 
531  // Override because the allocator needs to know the dynamic type
532  virtual void
533  _M_destroy() noexcept
534  {
535  __allocator_type __a(_M_impl._M_alloc());
536  __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
537  this->~_Sp_counted_ptr_inplace();
538  }
539 
540  private:
541  friend class __shared_count<_Lp>; // To be able to call _M_ptr().
542 
543  // No longer used, but code compiled against old libstdc++ headers
544  // might still call it from __shared_ptr ctor to get the pointer out.
545  virtual void*
546  _M_get_deleter(const std::type_info& __ti) noexcept override
547  {
548  auto __ptr = const_cast<typename remove_cv<_Tp>::type*>(_M_ptr());
549  // Check for the fake type_info first, so we don't try to access it
550  // as a real type_info object. Otherwise, check if it's the real
551  // type_info for this class. With RTTI enabled we can check directly,
552  // or call a library function to do it.
553  if (&__ti == &_Sp_make_shared_tag::_S_ti()
554  ||
555 #if __cpp_rtti
556  __ti == typeid(_Sp_make_shared_tag)
557 #else
558  _Sp_make_shared_tag::_S_eq(__ti)
559 #endif
560  )
561  return __ptr;
562  return nullptr;
563  }
564 
565  _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
566 
567  _Impl _M_impl;
568  };
569 
570  // The default deleter for shared_ptr<T[]> and shared_ptr<T[N]>.
571  struct __sp_array_delete
572  {
573  template<typename _Yp>
574  void operator()(_Yp* __p) const { delete[] __p; }
575  };
576 
577  template<_Lock_policy _Lp>
578  class __shared_count
579  {
580  template<typename _Tp>
581  struct __not_alloc_shared_tag { using type = void; };
582 
583  template<typename _Tp>
584  struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { };
585 
586  public:
587  constexpr __shared_count() noexcept : _M_pi(0)
588  { }
589 
590  template<typename _Ptr>
591  explicit
592  __shared_count(_Ptr __p) : _M_pi(0)
593  {
594  __try
595  {
596  _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
597  }
598  __catch(...)
599  {
600  delete __p;
601  __throw_exception_again;
602  }
603  }
604 
605  template<typename _Ptr>
606  __shared_count(_Ptr __p, /* is_array = */ false_type)
607  : __shared_count(__p)
608  { }
609 
610  template<typename _Ptr>
611  __shared_count(_Ptr __p, /* is_array = */ true_type)
612  : __shared_count(__p, __sp_array_delete{}, allocator<void>())
613  { }
614 
615  template<typename _Ptr, typename _Deleter,
616  typename = typename __not_alloc_shared_tag<_Deleter>::type>
617  __shared_count(_Ptr __p, _Deleter __d)
618  : __shared_count(__p, std::move(__d), allocator<void>())
619  { }
620 
621  template<typename _Ptr, typename _Deleter, typename _Alloc,
622  typename = typename __not_alloc_shared_tag<_Deleter>::type>
623  __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
624  {
625  typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
626  __try
627  {
628  typename _Sp_cd_type::__allocator_type __a2(__a);
629  auto __guard = std::__allocate_guarded(__a2);
630  _Sp_cd_type* __mem = __guard.get();
631  ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a));
632  _M_pi = __mem;
633  __guard = nullptr;
634  }
635  __catch(...)
636  {
637  __d(__p); // Call _Deleter on __p.
638  __throw_exception_again;
639  }
640  }
641 
642  template<typename _Tp, typename _Alloc, typename... _Args>
643  __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a,
644  _Args&&... __args)
645  {
646  typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
647  typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
648  auto __guard = std::__allocate_guarded(__a2);
649  _Sp_cp_type* __mem = __guard.get();
650  auto __pi = ::new (__mem)
651  _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
652  __guard = nullptr;
653  _M_pi = __pi;
654  __p = __pi->_M_ptr();
655  }
656 
657 #if _GLIBCXX_USE_DEPRECATED
658 #pragma GCC diagnostic push
659 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
660  // Special case for auto_ptr<_Tp> to provide the strong guarantee.
661  template<typename _Tp>
662  explicit
663  __shared_count(std::auto_ptr<_Tp>&& __r);
664 #pragma GCC diagnostic pop
665 #endif
666 
667  // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
668  template<typename _Tp, typename _Del>
669  explicit
670  __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
671  {
672  // _GLIBCXX_RESOLVE_LIB_DEFECTS
673  // 2415. Inconsistency between unique_ptr and shared_ptr
674  if (__r.get() == nullptr)
675  return;
676 
677  using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
678  using _Del2 = typename conditional<is_reference<_Del>::value,
679  reference_wrapper<typename remove_reference<_Del>::type>,
680  _Del>::type;
681  using _Sp_cd_type
682  = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
683  using _Alloc = allocator<_Sp_cd_type>;
684  using _Alloc_traits = allocator_traits<_Alloc>;
685  _Alloc __a;
686  _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
687  _Alloc_traits::construct(__a, __mem, __r.release(),
688  __r.get_deleter()); // non-throwing
689  _M_pi = __mem;
690  }
691 
692  // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
693  explicit __shared_count(const __weak_count<_Lp>& __r);
694 
695  // Does not throw if __r._M_get_use_count() == 0, caller must check.
696  explicit
697  __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept;
698 
699  ~__shared_count() noexcept
700  {
701  if (_M_pi != nullptr)
702  _M_pi->_M_release();
703  }
704 
705  __shared_count(const __shared_count& __r) noexcept
706  : _M_pi(__r._M_pi)
707  {
708  if (_M_pi != nullptr)
709  _M_pi->_M_add_ref_copy();
710  }
711 
712  __shared_count&
713  operator=(const __shared_count& __r) noexcept
714  {
715  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
716  if (__tmp != _M_pi)
717  {
718  if (__tmp != nullptr)
719  __tmp->_M_add_ref_copy();
720  if (_M_pi != nullptr)
721  _M_pi->_M_release();
722  _M_pi = __tmp;
723  }
724  return *this;
725  }
726 
727  void
728  _M_swap(__shared_count& __r) noexcept
729  {
730  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
731  __r._M_pi = _M_pi;
732  _M_pi = __tmp;
733  }
734 
735  long
736  _M_get_use_count() const noexcept
737  { return _M_pi ? _M_pi->_M_get_use_count() : 0; }
738 
739  bool
740  _M_unique() const noexcept
741  { return this->_M_get_use_count() == 1; }
742 
743  void*
744  _M_get_deleter(const std::type_info& __ti) const noexcept
745  { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; }
746 
747  bool
748  _M_less(const __shared_count& __rhs) const noexcept
749  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
750 
751  bool
752  _M_less(const __weak_count<_Lp>& __rhs) const noexcept
753  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
754 
755  // Friend function injected into enclosing namespace and found by ADL
756  friend inline bool
757  operator==(const __shared_count& __a, const __shared_count& __b) noexcept
758  { return __a._M_pi == __b._M_pi; }
759 
760  private:
761  friend class __weak_count<_Lp>;
762 
763  _Sp_counted_base<_Lp>* _M_pi;
764  };
765 
766 
767  template<_Lock_policy _Lp>
768  class __weak_count
769  {
770  public:
771  constexpr __weak_count() noexcept : _M_pi(nullptr)
772  { }
773 
774  __weak_count(const __shared_count<_Lp>& __r) noexcept
775  : _M_pi(__r._M_pi)
776  {
777  if (_M_pi != nullptr)
778  _M_pi->_M_weak_add_ref();
779  }
780 
781  __weak_count(const __weak_count& __r) noexcept
782  : _M_pi(__r._M_pi)
783  {
784  if (_M_pi != nullptr)
785  _M_pi->_M_weak_add_ref();
786  }
787 
788  __weak_count(__weak_count&& __r) noexcept
789  : _M_pi(__r._M_pi)
790  { __r._M_pi = nullptr; }
791 
792  ~__weak_count() noexcept
793  {
794  if (_M_pi != nullptr)
795  _M_pi->_M_weak_release();
796  }
797 
798  __weak_count&
799  operator=(const __shared_count<_Lp>& __r) noexcept
800  {
801  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
802  if (__tmp != nullptr)
803  __tmp->_M_weak_add_ref();
804  if (_M_pi != nullptr)
805  _M_pi->_M_weak_release();
806  _M_pi = __tmp;
807  return *this;
808  }
809 
810  __weak_count&
811  operator=(const __weak_count& __r) noexcept
812  {
813  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
814  if (__tmp != nullptr)
815  __tmp->_M_weak_add_ref();
816  if (_M_pi != nullptr)
817  _M_pi->_M_weak_release();
818  _M_pi = __tmp;
819  return *this;
820  }
821 
822  __weak_count&
823  operator=(__weak_count&& __r) noexcept
824  {
825  if (_M_pi != nullptr)
826  _M_pi->_M_weak_release();
827  _M_pi = __r._M_pi;
828  __r._M_pi = nullptr;
829  return *this;
830  }
831 
832  void
833  _M_swap(__weak_count& __r) noexcept
834  {
835  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
836  __r._M_pi = _M_pi;
837  _M_pi = __tmp;
838  }
839 
840  long
841  _M_get_use_count() const noexcept
842  { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
843 
844  bool
845  _M_less(const __weak_count& __rhs) const noexcept
846  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
847 
848  bool
849  _M_less(const __shared_count<_Lp>& __rhs) const noexcept
850  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
851 
852  // Friend function injected into enclosing namespace and found by ADL
853  friend inline bool
854  operator==(const __weak_count& __a, const __weak_count& __b) noexcept
855  { return __a._M_pi == __b._M_pi; }
856 
857  private:
858  friend class __shared_count<_Lp>;
859 
860  _Sp_counted_base<_Lp>* _M_pi;
861  };
862 
863  // Now that __weak_count is defined we can define this constructor:
864  template<_Lock_policy _Lp>
865  inline
866  __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
867  : _M_pi(__r._M_pi)
868  {
869  if (_M_pi == nullptr || !_M_pi->_M_add_ref_lock_nothrow())
870  __throw_bad_weak_ptr();
871  }
872 
873  // Now that __weak_count is defined we can define this constructor:
874  template<_Lock_policy _Lp>
875  inline
876  __shared_count<_Lp>::
877  __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept
878  : _M_pi(__r._M_pi)
879  {
880  if (_M_pi && !_M_pi->_M_add_ref_lock_nothrow())
881  _M_pi = nullptr;
882  }
883 
884 #define __cpp_lib_shared_ptr_arrays 201611L
885 
886  // Helper traits for shared_ptr of array:
887 
888  // A pointer type Y* is said to be compatible with a pointer type T* when
889  // either Y* is convertible to T* or Y is U[N] and T is U cv [].
890  template<typename _Yp_ptr, typename _Tp_ptr>
891  struct __sp_compatible_with
892  : false_type
893  { };
894 
895  template<typename _Yp, typename _Tp>
896  struct __sp_compatible_with<_Yp*, _Tp*>
897  : is_convertible<_Yp*, _Tp*>::type
898  { };
899 
900  template<typename _Up, size_t _Nm>
901  struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]>
902  : true_type
903  { };
904 
905  template<typename _Up, size_t _Nm>
906  struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]>
907  : true_type
908  { };
909 
910  template<typename _Up, size_t _Nm>
911  struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]>
912  : true_type
913  { };
914 
915  template<typename _Up, size_t _Nm>
916  struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]>
917  : true_type
918  { };
919 
920  // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N].
921  template<typename _Up, size_t _Nm, typename _Yp, typename = void>
922  struct __sp_is_constructible_arrN
923  : false_type
924  { };
925 
926  template<typename _Up, size_t _Nm, typename _Yp>
927  struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
928  : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
929  { };
930 
931  // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[].
932  template<typename _Up, typename _Yp, typename = void>
933  struct __sp_is_constructible_arr
934  : false_type
935  { };
936 
937  template<typename _Up, typename _Yp>
938  struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
939  : is_convertible<_Yp(*)[], _Up(*)[]>::type
940  { };
941 
942  // Trait to check if shared_ptr<T> can be constructed from Y*.
943  template<typename _Tp, typename _Yp>
944  struct __sp_is_constructible;
945 
946  // When T is U[N], Y(*)[N] shall be convertible to T*;
947  template<typename _Up, size_t _Nm, typename _Yp>
948  struct __sp_is_constructible<_Up[_Nm], _Yp>
949  : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
950  { };
951 
952  // when T is U[], Y(*)[] shall be convertible to T*;
953  template<typename _Up, typename _Yp>
954  struct __sp_is_constructible<_Up[], _Yp>
955  : __sp_is_constructible_arr<_Up, _Yp>::type
956  { };
957 
958  // otherwise, Y* shall be convertible to T*.
959  template<typename _Tp, typename _Yp>
960  struct __sp_is_constructible
961  : is_convertible<_Yp*, _Tp*>::type
962  { };
963 
964 
965  // Define operator* and operator-> for shared_ptr<T>.
966  template<typename _Tp, _Lock_policy _Lp,
967  bool = is_array<_Tp>::value, bool = is_void<_Tp>::value>
968  class __shared_ptr_access
969  {
970  public:
971  using element_type = _Tp;
972 
973  element_type&
974  operator*() const noexcept
975  {
976  __glibcxx_assert(_M_get() != nullptr);
977  return *_M_get();
978  }
979 
980  element_type*
981  operator->() const noexcept
982  {
983  _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
984  return _M_get();
985  }
986 
987  private:
988  element_type*
989  _M_get() const noexcept
990  { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
991  };
992 
993  // Define operator-> for shared_ptr<cv void>.
994  template<typename _Tp, _Lock_policy _Lp>
995  class __shared_ptr_access<_Tp, _Lp, false, true>
996  {
997  public:
998  using element_type = _Tp;
999 
1000  element_type*
1001  operator->() const noexcept
1002  {
1003  auto __ptr = static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get();
1004  _GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr);
1005  return __ptr;
1006  }
1007  };
1008 
1009  // Define operator[] for shared_ptr<T[]> and shared_ptr<T[N]>.
1010  template<typename _Tp, _Lock_policy _Lp>
1011  class __shared_ptr_access<_Tp, _Lp, true, false>
1012  {
1013  public:
1014  using element_type = typename remove_extent<_Tp>::type;
1015 
1016 #if __cplusplus <= 201402L
1017  [[__deprecated__("shared_ptr<T[]>::operator* is absent from C++17")]]
1018  element_type&
1019  operator*() const noexcept
1020  {
1021  __glibcxx_assert(_M_get() != nullptr);
1022  return *_M_get();
1023  }
1024 
1025  [[__deprecated__("shared_ptr<T[]>::operator-> is absent from C++17")]]
1026  element_type*
1027  operator->() const noexcept
1028  {
1029  _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
1030  return _M_get();
1031  }
1032 #endif
1033 
1034  element_type&
1035  operator[](ptrdiff_t __i) const
1036  {
1037  __glibcxx_assert(_M_get() != nullptr);
1038  __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value);
1039  return _M_get()[__i];
1040  }
1041 
1042  private:
1043  element_type*
1044  _M_get() const noexcept
1045  { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
1046  };
1047 
1048  template<typename _Tp, _Lock_policy _Lp>
1049  class __shared_ptr
1050  : public __shared_ptr_access<_Tp, _Lp>
1051  {
1052  public:
1053  using element_type = typename remove_extent<_Tp>::type;
1054 
1055  private:
1056  // Constraint for taking ownership of a pointer of type _Yp*:
1057  template<typename _Yp>
1058  using _SafeConv
1059  = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type;
1060 
1061  // Constraint for construction from shared_ptr and weak_ptr:
1062  template<typename _Yp, typename _Res = void>
1063  using _Compatible = typename
1064  enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
1065 
1066  // Constraint for assignment from shared_ptr and weak_ptr:
1067  template<typename _Yp>
1068  using _Assignable = _Compatible<_Yp, __shared_ptr&>;
1069 
1070  // Constraint for construction from unique_ptr:
1071  template<typename _Yp, typename _Del, typename _Res = void,
1072  typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer>
1073  using _UniqCompatible = typename enable_if<__and_<
1074  __sp_compatible_with<_Yp*, _Tp*>, is_convertible<_Ptr, element_type*>
1075  >::value, _Res>::type;
1076 
1077  // Constraint for assignment from unique_ptr:
1078  template<typename _Yp, typename _Del>
1079  using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>;
1080 
1081  public:
1082 
1083 #if __cplusplus > 201402L
1084  using weak_type = __weak_ptr<_Tp, _Lp>;
1085 #endif
1086 
1087  constexpr __shared_ptr() noexcept
1088  : _M_ptr(0), _M_refcount()
1089  { }
1090 
1091  template<typename _Yp, typename = _SafeConv<_Yp>>
1092  explicit
1093  __shared_ptr(_Yp* __p)
1094  : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type())
1095  {
1096  static_assert( !is_void<_Yp>::value, "incomplete type" );
1097  static_assert( sizeof(_Yp) > 0, "incomplete type" );
1098  _M_enable_shared_from_this_with(__p);
1099  }
1100 
1101  template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>>
1102  __shared_ptr(_Yp* __p, _Deleter __d)
1103  : _M_ptr(__p), _M_refcount(__p, std::move(__d))
1104  {
1105  static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1106  "deleter expression d(p) is well-formed");
1107  _M_enable_shared_from_this_with(__p);
1108  }
1109 
1110  template<typename _Yp, typename _Deleter, typename _Alloc,
1111  typename = _SafeConv<_Yp>>
1112  __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
1113  : _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a))
1114  {
1115  static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1116  "deleter expression d(p) is well-formed");
1117  _M_enable_shared_from_this_with(__p);
1118  }
1119 
1120  template<typename _Deleter>
1121  __shared_ptr(nullptr_t __p, _Deleter __d)
1122  : _M_ptr(0), _M_refcount(__p, std::move(__d))
1123  { }
1124 
1125  template<typename _Deleter, typename _Alloc>
1126  __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
1127  : _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a))
1128  { }
1129 
1130  // Aliasing constructor
1131  template<typename _Yp>
1132  __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r,
1133  element_type* __p) noexcept
1134  : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
1135  { }
1136 
1137  // Aliasing constructor
1138  template<typename _Yp>
1139  __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r,
1140  element_type* __p) noexcept
1141  : _M_ptr(__p), _M_refcount()
1142  {
1143  _M_refcount._M_swap(__r._M_refcount);
1144  __r._M_ptr = nullptr;
1145  }
1146 
1147  __shared_ptr(const __shared_ptr&) noexcept = default;
1148  __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
1149  ~__shared_ptr() = default;
1150 
1151  template<typename _Yp, typename = _Compatible<_Yp>>
1152  __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1153  : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1154  { }
1155 
1156  __shared_ptr(__shared_ptr&& __r) noexcept
1157  : _M_ptr(__r._M_ptr), _M_refcount()
1158  {
1159  _M_refcount._M_swap(__r._M_refcount);
1160  __r._M_ptr = nullptr;
1161  }
1162 
1163  template<typename _Yp, typename = _Compatible<_Yp>>
1164  __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1165  : _M_ptr(__r._M_ptr), _M_refcount()
1166  {
1167  _M_refcount._M_swap(__r._M_refcount);
1168  __r._M_ptr = nullptr;
1169  }
1170 
1171  template<typename _Yp, typename = _Compatible<_Yp>>
1172  explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r)
1173  : _M_refcount(__r._M_refcount) // may throw
1174  {
1175  // It is now safe to copy __r._M_ptr, as
1176  // _M_refcount(__r._M_refcount) did not throw.
1177  _M_ptr = __r._M_ptr;
1178  }
1179 
1180  // If an exception is thrown this constructor has no effect.
1181  template<typename _Yp, typename _Del,
1182  typename = _UniqCompatible<_Yp, _Del>>
1183  __shared_ptr(unique_ptr<_Yp, _Del>&& __r)
1184  : _M_ptr(__r.get()), _M_refcount()
1185  {
1186  auto __raw = __to_address(__r.get());
1187  _M_refcount = __shared_count<_Lp>(std::move(__r));
1188  _M_enable_shared_from_this_with(__raw);
1189  }
1190 
1191 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
1192  protected:
1193  // If an exception is thrown this constructor has no effect.
1194  template<typename _Tp1, typename _Del,
1195  typename enable_if<__and_<
1196  __not_<is_array<_Tp>>, is_array<_Tp1>,
1197  is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*>
1198  >::value, bool>::type = true>
1199  __shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete)
1200  : _M_ptr(__r.get()), _M_refcount()
1201  {
1202  auto __raw = __to_address(__r.get());
1203  _M_refcount = __shared_count<_Lp>(std::move(__r));
1204  _M_enable_shared_from_this_with(__raw);
1205  }
1206  public:
1207 #endif
1208 
1209 #if _GLIBCXX_USE_DEPRECATED
1210 #pragma GCC diagnostic push
1211 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1212  // Postcondition: use_count() == 1 and __r.get() == 0
1213  template<typename _Yp, typename = _Compatible<_Yp>>
1214  __shared_ptr(auto_ptr<_Yp>&& __r);
1215 #pragma GCC diagnostic pop
1216 #endif
1217 
1218  constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
1219 
1220  template<typename _Yp>
1221  _Assignable<_Yp>
1222  operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1223  {
1224  _M_ptr = __r._M_ptr;
1225  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
1226  return *this;
1227  }
1228 
1229 #if _GLIBCXX_USE_DEPRECATED
1230 #pragma GCC diagnostic push
1231 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1232  template<typename _Yp>
1233  _Assignable<_Yp>
1234  operator=(auto_ptr<_Yp>&& __r)
1235  {
1236  __shared_ptr(std::move(__r)).swap(*this);
1237  return *this;
1238  }
1239 #pragma GCC diagnostic pop
1240 #endif
1241 
1242  __shared_ptr&
1243  operator=(__shared_ptr&& __r) noexcept
1244  {
1245  __shared_ptr(std::move(__r)).swap(*this);
1246  return *this;
1247  }
1248 
1249  template<class _Yp>
1250  _Assignable<_Yp>
1251  operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1252  {
1253  __shared_ptr(std::move(__r)).swap(*this);
1254  return *this;
1255  }
1256 
1257  template<typename _Yp, typename _Del>
1258  _UniqAssignable<_Yp, _Del>
1259  operator=(unique_ptr<_Yp, _Del>&& __r)
1260  {
1261  __shared_ptr(std::move(__r)).swap(*this);
1262  return *this;
1263  }
1264 
1265  void
1266  reset() noexcept
1267  { __shared_ptr().swap(*this); }
1268 
1269  template<typename _Yp>
1270  _SafeConv<_Yp>
1271  reset(_Yp* __p) // _Yp must be complete.
1272  {
1273  // Catch self-reset errors.
1274  __glibcxx_assert(__p == nullptr || __p != _M_ptr);
1275  __shared_ptr(__p).swap(*this);
1276  }
1277 
1278  template<typename _Yp, typename _Deleter>
1279  _SafeConv<_Yp>
1280  reset(_Yp* __p, _Deleter __d)
1281  { __shared_ptr(__p, std::move(__d)).swap(*this); }
1282 
1283  template<typename _Yp, typename _Deleter, typename _Alloc>
1284  _SafeConv<_Yp>
1285  reset(_Yp* __p, _Deleter __d, _Alloc __a)
1286  { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); }
1287 
1288  /// Return the stored pointer.
1289  element_type*
1290  get() const noexcept
1291  { return _M_ptr; }
1292 
1293  /// Return true if the stored pointer is not null.
1294  explicit operator bool() const noexcept
1295  { return _M_ptr != nullptr; }
1296 
1297  /// Return true if use_count() == 1.
1298  bool
1299  unique() const noexcept
1300  { return _M_refcount._M_unique(); }
1301 
1302  /// If *this owns a pointer, return the number of owners, otherwise zero.
1303  long
1304  use_count() const noexcept
1305  { return _M_refcount._M_get_use_count(); }
1306 
1307  /// Exchange both the owned pointer and the stored pointer.
1308  void
1309  swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
1310  {
1311  std::swap(_M_ptr, __other._M_ptr);
1312  _M_refcount._M_swap(__other._M_refcount);
1313  }
1314 
1315  /** @brief Define an ordering based on ownership.
1316  *
1317  * This function defines a strict weak ordering between two shared_ptr
1318  * or weak_ptr objects, such that one object is less than the other
1319  * unless they share ownership of the same pointer, or are both empty.
1320  * @{
1321  */
1322  template<typename _Tp1>
1323  bool
1324  owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1325  { return _M_refcount._M_less(__rhs._M_refcount); }
1326 
1327  template<typename _Tp1>
1328  bool
1329  owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1330  { return _M_refcount._M_less(__rhs._M_refcount); }
1331  // @}
1332 
1333  protected:
1334  // This constructor is non-standard, it is used by allocate_shared.
1335  template<typename _Alloc, typename... _Args>
1336  __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
1337  : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
1338  { _M_enable_shared_from_this_with(_M_ptr); }
1339 
1340  template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
1341  typename... _Args>
1342  friend __shared_ptr<_Tp1, _Lp1>
1343  __allocate_shared(const _Alloc& __a, _Args&&... __args);
1344 
1345  // This constructor is used by __weak_ptr::lock() and
1346  // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
1347  __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) noexcept
1348  : _M_refcount(__r._M_refcount, std::nothrow)
1349  {
1350  _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr;
1351  }
1352 
1353  friend class __weak_ptr<_Tp, _Lp>;
1354 
1355  private:
1356 
1357  template<typename _Yp>
1358  using __esft_base_t = decltype(__enable_shared_from_this_base(
1359  std::declval<const __shared_count<_Lp>&>(),
1360  std::declval<_Yp*>()));
1361 
1362  // Detect an accessible and unambiguous enable_shared_from_this base.
1363  template<typename _Yp, typename = void>
1364  struct __has_esft_base
1365  : false_type { };
1366 
1367  template<typename _Yp>
1368  struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
1369  : __not_<is_array<_Tp>> { }; // No enable shared_from_this for arrays
1370 
1371  template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1372  typename enable_if<__has_esft_base<_Yp2>::value>::type
1373  _M_enable_shared_from_this_with(_Yp* __p) noexcept
1374  {
1375  if (auto __base = __enable_shared_from_this_base(_M_refcount, __p))
1376  __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount);
1377  }
1378 
1379  template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1380  typename enable_if<!__has_esft_base<_Yp2>::value>::type
1381  _M_enable_shared_from_this_with(_Yp*) noexcept
1382  { }
1383 
1384  void*
1385  _M_get_deleter(const std::type_info& __ti) const noexcept
1386  { return _M_refcount._M_get_deleter(__ti); }
1387 
1388  template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1389  template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1390 
1391  template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
1392  friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
1393 
1394  template<typename _Del, typename _Tp1>
1395  friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept;
1396 
1397  element_type* _M_ptr; // Contained pointer.
1398  __shared_count<_Lp> _M_refcount; // Reference counter.
1399  };
1400 
1401 
1402  // 20.7.2.2.7 shared_ptr comparisons
1403  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1404  inline bool
1405  operator==(const __shared_ptr<_Tp1, _Lp>& __a,
1406  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1407  { return __a.get() == __b.get(); }
1408 
1409  template<typename _Tp, _Lock_policy _Lp>
1410  inline bool
1411  operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1412  { return !__a; }
1413 
1414 #ifdef __cpp_lib_three_way_comparison
1415  template<typename _Tp, typename _Up, _Lock_policy _Lp>
1416  inline strong_ordering
1417  operator<=>(const __shared_ptr<_Tp, _Lp>& __a,
1418  const __shared_ptr<_Up, _Lp>& __b) noexcept
1419  { return compare_three_way()(__a.get(), __b.get()); }
1420 
1421  template<typename _Tp, _Lock_policy _Lp>
1422  inline strong_ordering
1423  operator<=>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1424  {
1425  using pointer = typename __shared_ptr<_Tp, _Lp>::element_type*;
1426  return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
1427  }
1428 #else
1429  template<typename _Tp, _Lock_policy _Lp>
1430  inline bool
1431  operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1432  { return !__a; }
1433 
1434  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1435  inline bool
1436  operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
1437  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1438  { return __a.get() != __b.get(); }
1439 
1440  template<typename _Tp, _Lock_policy _Lp>
1441  inline bool
1442  operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1443  { return (bool)__a; }
1444 
1445  template<typename _Tp, _Lock_policy _Lp>
1446  inline bool
1447  operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1448  { return (bool)__a; }
1449 
1450  template<typename _Tp, typename _Up, _Lock_policy _Lp>
1451  inline bool
1452  operator<(const __shared_ptr<_Tp, _Lp>& __a,
1453  const __shared_ptr<_Up, _Lp>& __b) noexcept
1454  {
1455  using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1456  using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type;
1457  using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
1458  return less<_Vp>()(__a.get(), __b.get());
1459  }
1460 
1461  template<typename _Tp, _Lock_policy _Lp>
1462  inline bool
1463  operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1464  {
1465  using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1466  return less<_Tp_elt*>()(__a.get(), nullptr);
1467  }
1468 
1469  template<typename _Tp, _Lock_policy _Lp>
1470  inline bool
1471  operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1472  {
1473  using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1474  return less<_Tp_elt*>()(nullptr, __a.get());
1475  }
1476 
1477  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1478  inline bool
1479  operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
1480  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1481  { return !(__b < __a); }
1482 
1483  template<typename _Tp, _Lock_policy _Lp>
1484  inline bool
1485  operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1486  { return !(nullptr < __a); }
1487 
1488  template<typename _Tp, _Lock_policy _Lp>
1489  inline bool
1490  operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1491  { return !(__a < nullptr); }
1492 
1493  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1494  inline bool
1495  operator>(const __shared_ptr<_Tp1, _Lp>& __a,
1496  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1497  { return (__b < __a); }
1498 
1499  template<typename _Tp, _Lock_policy _Lp>
1500  inline bool
1501  operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1502  { return nullptr < __a; }
1503 
1504  template<typename _Tp, _Lock_policy _Lp>
1505  inline bool
1506  operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1507  { return __a < nullptr; }
1508 
1509  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1510  inline bool
1511  operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
1512  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1513  { return !(__a < __b); }
1514 
1515  template<typename _Tp, _Lock_policy _Lp>
1516  inline bool
1517  operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1518  { return !(__a < nullptr); }
1519 
1520  template<typename _Tp, _Lock_policy _Lp>
1521  inline bool
1522  operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1523  { return !(nullptr < __a); }
1524 #endif // three-way comparison
1525 
1526  // 20.7.2.2.8 shared_ptr specialized algorithms.
1527  template<typename _Tp, _Lock_policy _Lp>
1528  inline void
1529  swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
1530  { __a.swap(__b); }
1531 
1532  // 20.7.2.2.9 shared_ptr casts
1533 
1534  // The seemingly equivalent code:
1535  // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
1536  // will eventually result in undefined behaviour, attempting to
1537  // delete the same object twice.
1538  /// static_pointer_cast
1539  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1540  inline __shared_ptr<_Tp, _Lp>
1541  static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1542  {
1543  using _Sp = __shared_ptr<_Tp, _Lp>;
1544  return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
1545  }
1546 
1547  // The seemingly equivalent code:
1548  // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
1549  // will eventually result in undefined behaviour, attempting to
1550  // delete the same object twice.
1551  /// const_pointer_cast
1552  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1553  inline __shared_ptr<_Tp, _Lp>
1554  const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1555  {
1556  using _Sp = __shared_ptr<_Tp, _Lp>;
1557  return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
1558  }
1559 
1560  // The seemingly equivalent code:
1561  // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
1562  // will eventually result in undefined behaviour, attempting to
1563  // delete the same object twice.
1564  /// dynamic_pointer_cast
1565  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1566  inline __shared_ptr<_Tp, _Lp>
1567  dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1568  {
1569  using _Sp = __shared_ptr<_Tp, _Lp>;
1570  if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
1571  return _Sp(__r, __p);
1572  return _Sp();
1573  }
1574 
1575 #if __cplusplus > 201402L
1576  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1577  inline __shared_ptr<_Tp, _Lp>
1578  reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1579  {
1580  using _Sp = __shared_ptr<_Tp, _Lp>;
1581  return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
1582  }
1583 #endif
1584 
1585  template<typename _Tp, _Lock_policy _Lp>
1586  class __weak_ptr
1587  {
1588  template<typename _Yp, typename _Res = void>
1589  using _Compatible = typename
1590  enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
1591 
1592  // Constraint for assignment from shared_ptr and weak_ptr:
1593  template<typename _Yp>
1594  using _Assignable = _Compatible<_Yp, __weak_ptr&>;
1595 
1596  public:
1597  using element_type = typename remove_extent<_Tp>::type;
1598 
1599  constexpr __weak_ptr() noexcept
1600  : _M_ptr(nullptr), _M_refcount()
1601  { }
1602 
1603  __weak_ptr(const __weak_ptr&) noexcept = default;
1604 
1605  ~__weak_ptr() = default;
1606 
1607  // The "obvious" converting constructor implementation:
1608  //
1609  // template<typename _Tp1>
1610  // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
1611  // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
1612  // { }
1613  //
1614  // has a serious problem.
1615  //
1616  // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
1617  // conversion may require access to *__r._M_ptr (virtual inheritance).
1618  //
1619  // It is not possible to avoid spurious access violations since
1620  // in multithreaded programs __r._M_ptr may be invalidated at any point.
1621  template<typename _Yp, typename = _Compatible<_Yp>>
1622  __weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept
1623  : _M_refcount(__r._M_refcount)
1624  { _M_ptr = __r.lock().get(); }
1625 
1626  template<typename _Yp, typename = _Compatible<_Yp>>
1627  __weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1628  : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1629  { }
1630 
1631  __weak_ptr(__weak_ptr&& __r) noexcept
1632  : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
1633  { __r._M_ptr = nullptr; }
1634 
1635  template<typename _Yp, typename = _Compatible<_Yp>>
1636  __weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept
1637  : _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount))
1638  { __r._M_ptr = nullptr; }
1639 
1640  __weak_ptr&
1641  operator=(const __weak_ptr& __r) noexcept = default;
1642 
1643  template<typename _Yp>
1644  _Assignable<_Yp>
1645  operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept
1646  {
1647  _M_ptr = __r.lock().get();
1648  _M_refcount = __r._M_refcount;
1649  return *this;
1650  }
1651 
1652  template<typename _Yp>
1653  _Assignable<_Yp>
1654  operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1655  {
1656  _M_ptr = __r._M_ptr;
1657  _M_refcount = __r._M_refcount;
1658  return *this;
1659  }
1660 
1661  __weak_ptr&
1662  operator=(__weak_ptr&& __r) noexcept
1663  {
1664  _M_ptr = __r._M_ptr;
1665  _M_refcount = std::move(__r._M_refcount);
1666  __r._M_ptr = nullptr;
1667  return *this;
1668  }
1669 
1670  template<typename _Yp>
1671  _Assignable<_Yp>
1672  operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept
1673  {
1674  _M_ptr = __r.lock().get();
1675  _M_refcount = std::move(__r._M_refcount);
1676  __r._M_ptr = nullptr;
1677  return *this;
1678  }
1679 
1680  __shared_ptr<_Tp, _Lp>
1681  lock() const noexcept
1682  { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); }
1683 
1684  long
1685  use_count() const noexcept
1686  { return _M_refcount._M_get_use_count(); }
1687 
1688  bool
1689  expired() const noexcept
1690  { return _M_refcount._M_get_use_count() == 0; }
1691 
1692  template<typename _Tp1>
1693  bool
1694  owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept
1695  { return _M_refcount._M_less(__rhs._M_refcount); }
1696 
1697  template<typename _Tp1>
1698  bool
1699  owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept
1700  { return _M_refcount._M_less(__rhs._M_refcount); }
1701 
1702  void
1703  reset() noexcept
1704  { __weak_ptr().swap(*this); }
1705 
1706  void
1707  swap(__weak_ptr& __s) noexcept
1708  {
1709  std::swap(_M_ptr, __s._M_ptr);
1710  _M_refcount._M_swap(__s._M_refcount);
1711  }
1712 
1713  private:
1714  // Used by __enable_shared_from_this.
1715  void
1716  _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
1717  {
1718  if (use_count() == 0)
1719  {
1720  _M_ptr = __ptr;
1721  _M_refcount = __refcount;
1722  }
1723  }
1724 
1725  template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1726  template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1727  friend class __enable_shared_from_this<_Tp, _Lp>;
1728  friend class enable_shared_from_this<_Tp>;
1729 
1730  element_type* _M_ptr; // Contained pointer.
1731  __weak_count<_Lp> _M_refcount; // Reference counter.
1732  };
1733 
1734  // 20.7.2.3.6 weak_ptr specialized algorithms.
1735  template<typename _Tp, _Lock_policy _Lp>
1736  inline void
1737  swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
1738  { __a.swap(__b); }
1739 
1740  template<typename _Tp, typename _Tp1>
1741  struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
1742  {
1743  bool
1744  operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept
1745  { return __lhs.owner_before(__rhs); }
1746 
1747  bool
1748  operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept
1749  { return __lhs.owner_before(__rhs); }
1750 
1751  bool
1752  operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept
1753  { return __lhs.owner_before(__rhs); }
1754  };
1755 
1756  template<>
1757  struct _Sp_owner_less<void, void>
1758  {
1759  template<typename _Tp, typename _Up>
1760  auto
1761  operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept
1762  -> decltype(__lhs.owner_before(__rhs))
1763  { return __lhs.owner_before(__rhs); }
1764 
1765  using is_transparent = void;
1766  };
1767 
1768  template<typename _Tp, _Lock_policy _Lp>
1769  struct owner_less<__shared_ptr<_Tp, _Lp>>
1770  : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
1771  { };
1772 
1773  template<typename _Tp, _Lock_policy _Lp>
1774  struct owner_less<__weak_ptr<_Tp, _Lp>>
1775  : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
1776  { };
1777 
1778 
1779  template<typename _Tp, _Lock_policy _Lp>
1780  class __enable_shared_from_this
1781  {
1782  protected:
1783  constexpr __enable_shared_from_this() noexcept { }
1784 
1785  __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
1786 
1787  __enable_shared_from_this&
1788  operator=(const __enable_shared_from_this&) noexcept
1789  { return *this; }
1790 
1791  ~__enable_shared_from_this() { }
1792 
1793  public:
1794  __shared_ptr<_Tp, _Lp>
1795  shared_from_this()
1796  { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
1797 
1798  __shared_ptr<const _Tp, _Lp>
1799  shared_from_this() const
1800  { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
1801 
1802 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1803  __weak_ptr<_Tp, _Lp>
1804  weak_from_this() noexcept
1805  { return this->_M_weak_this; }
1806 
1807  __weak_ptr<const _Tp, _Lp>
1808  weak_from_this() const noexcept
1809  { return this->_M_weak_this; }
1810 #endif
1811 
1812  private:
1813  template<typename _Tp1>
1814  void
1815  _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
1816  { _M_weak_this._M_assign(__p, __n); }
1817 
1818  friend const __enable_shared_from_this*
1819  __enable_shared_from_this_base(const __shared_count<_Lp>&,
1820  const __enable_shared_from_this* __p)
1821  { return __p; }
1822 
1823  template<typename, _Lock_policy>
1824  friend class __shared_ptr;
1825 
1826  mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
1827  };
1828 
1829  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
1830  typename _Alloc, typename... _Args>
1831  inline __shared_ptr<_Tp, _Lp>
1832  __allocate_shared(const _Alloc& __a, _Args&&... __args)
1833  {
1834  return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a},
1835  std::forward<_Args>(__args)...);
1836  }
1837 
1838  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
1839  typename... _Args>
1840  inline __shared_ptr<_Tp, _Lp>
1841  __make_shared(_Args&&... __args)
1842  {
1843  typedef typename std::remove_const<_Tp>::type _Tp_nc;
1844  return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
1845  std::forward<_Args>(__args)...);
1846  }
1847 
1848  /// std::hash specialization for __shared_ptr.
1849  template<typename _Tp, _Lock_policy _Lp>
1850  struct hash<__shared_ptr<_Tp, _Lp>>
1851  : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
1852  {
1853  size_t
1854  operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
1855  {
1857  __s.get());
1858  }
1859  };
1860 
1861 _GLIBCXX_END_NAMESPACE_VERSION
1862 } // namespace
1863 
1864 #endif // _SHARED_PTR_BASE_H
auto_ptr & operator=(auto_ptr &__a)
auto_ptr assignment operator.
Definition: auto_ptr.h:47
void reset(element_type *__p=0)
Forcibly deletes the managed object.
Definition: auto_ptr.h:151
element_type * operator->() const
Smart pointer dereferencing.
Definition: auto_ptr.h:105
auto_ptr(element_type *__p=0)
An auto_ptr is usually constructed from a raw pointer.
Definition: auto_ptr.h:14
_Tp element_type
The pointed-to type.
Definition: auto_ptr.h:5
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:392
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
Definition: type_traits:75
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
Definition: type_traits:78
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:49
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:101
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:76
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
Definition: any:412
void lock(_L1 &__l1, _L2 &__l2, _L3 &... __l3)
Generic lock.
Definition: mutex:591
ISO C++ entities toplevel namespace is std.
__allocated_ptr< _Alloc > __allocate_guarded(_Alloc &__a)
Allocate space for a single object using __a.
Definition: allocated_ptr.h:95
__shared_ptr< _Tp, _Lp > static_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
static_pointer_cast
__shared_ptr< _Tp, _Lp > const_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
const_pointer_cast
__shared_ptr< _Tp, _Lp > dynamic_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
dynamic_pointer_cast
constexpr _Iterator __base(_Iterator __it)
Part of RTTI.
Definition: typeinfo:89
Primary class template hash.
static constexpr auto construct(_Alloc &__a, _Tp *__p, _Args &&... __args) noexcept(noexcept(_S_construct(__a, __p, std::forward< _Args >(__args)...))) -> decltype(_S_construct(__a, __p, std::forward< _Args >(__args)...))
Construct an object of type _Tp.
static constexpr void destroy(_Alloc &__a, _Tp *__p) noexcept(noexcept(_S_destroy(__a, __p, 0)))
Destroy an object of type _Tp.
The standard allocator, as per [20.4].
Definition: allocator.h:117
Base class for all library exceptions.
Definition: exception.h:61
Exception possibly thrown by shared_ptr.
virtual char const * what() const noexcept
One of the comparison functors.
Definition: stl_function.h:382
20.7.1.2 unique_ptr for single objects.
Definition: unique_ptr.h:243
A simple smart pointer providing strict ownership semantics.
Definition: auto_ptr.h:90
Scoped lock idiom.
Definition: concurrence.h:229