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-2026 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 >= 202002L
64 # include <compare>
65 # include <bits/align.h> // std::align
66 # include <bits/stl_uninitialized.h>
67 #endif
68 
69 namespace std _GLIBCXX_VISIBILITY(default)
70 {
71 _GLIBCXX_BEGIN_NAMESPACE_VERSION
72 
73 #if _GLIBCXX_USE_DEPRECATED
74 #pragma GCC diagnostic push
75 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
76  template<typename> class auto_ptr;
77 #pragma GCC diagnostic pop
78 #endif
79 
80  /**
81  * @brief Exception possibly thrown by @c shared_ptr.
82  * @ingroup exceptions
83  */
85  {
86  public:
87  virtual char const* what() const noexcept;
88 
89  virtual ~bad_weak_ptr() noexcept;
90  };
91 
92  // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
93  inline void
94  __throw_bad_weak_ptr()
95  { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
96 
97  using __gnu_cxx::_Lock_policy;
98  using __gnu_cxx::__default_lock_policy;
99  using __gnu_cxx::_S_single;
100  using __gnu_cxx::_S_mutex;
101  using __gnu_cxx::_S_atomic;
102 
103  // Empty helper class except when the template argument is _S_mutex.
104  template<_Lock_policy _Lp>
105  class _Mutex_base
106  {
107  protected:
108  // The atomic policy uses fully-fenced builtins, single doesn't care.
109  enum { _S_need_barriers = 0 };
110  };
111 
112  template<>
113  class _Mutex_base<_S_mutex>
114  : public __gnu_cxx::__mutex
115  {
116  protected:
117  // This policy is used when atomic builtins are not available.
118  // The replacement atomic operations might not have the necessary
119  // memory barriers.
120  enum { _S_need_barriers = 1 };
121  };
122 
123  template<_Lock_policy _Lp = __default_lock_policy>
124  class _Sp_counted_base
125  : public _Mutex_base<_Lp>
126  {
127  public:
128  _Sp_counted_base() noexcept
129  : _M_use_count(1), _M_weak_count(1) { }
130 
131  virtual
132  ~_Sp_counted_base() noexcept
133  { }
134 
135  // Called when _M_use_count drops to zero, to release the resources
136  // managed by *this.
137  virtual void
138  _M_dispose() noexcept = 0;
139 
140  // Called when _M_weak_count drops to zero.
141  virtual void
142  _M_destroy() noexcept
143  { delete this; }
144 
145  virtual void*
146  _M_get_deleter(const std::type_info&) noexcept = 0;
147 
148  // Increment the use count (used when the count is greater than zero).
149  void
150  _M_add_ref_copy()
151  { _S_chk(__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1)); }
152 
153  // Increment the use count if it is non-zero, throw otherwise.
154  void
155  _M_add_ref_lock()
156  {
157  if (!_M_add_ref_lock_nothrow())
158  __throw_bad_weak_ptr();
159  }
160 
161  // Increment the use count if it is non-zero.
162  bool
163  _M_add_ref_lock_nothrow() noexcept;
164 
165  // Decrement the use count.
166  void
167  _M_release() noexcept;
168 
169  // Called by _M_release() when the use count reaches zero.
170  void
171  _M_release_last_use() noexcept
172  {
173  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
174  _M_dispose();
175  // There must be a memory barrier between dispose() and destroy()
176  // to ensure that the effects of dispose() are observed in the
177  // thread that runs destroy().
178  // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
179  if (_Mutex_base<_Lp>::_S_need_barriers)
180  {
181  __atomic_thread_fence (__ATOMIC_ACQ_REL);
182  }
183 
184  // Be race-detector-friendly. For more info see bits/c++config.
185  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
186  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
187  -1) == 1)
188  {
189  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
190  _M_destroy();
191  }
192  }
193 
194  // As above, but 'noinline' to reduce code size on the cold path.
195  __attribute__((__noinline__))
196  void
197  _M_release_last_use_cold() noexcept
198  { _M_release_last_use(); }
199 
200  // Increment the weak count.
201  void
202  _M_weak_add_ref() noexcept
203  {
204  // _M_weak_count can always use negative values because it cannot be
205  // observed by users (unlike _M_use_count). See _S_chk for details.
206  constexpr _Atomic_word __max = -1;
207  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, 1) == __max)
208  [[__unlikely__]] __builtin_trap();
209  }
210 
211  // Decrement the weak count.
212  void
213  _M_weak_release() noexcept
214  {
215  // Be race-detector-friendly. For more info see bits/c++config.
216  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
217  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
218  {
219  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
220  if (_Mutex_base<_Lp>::_S_need_barriers)
221  {
222  // See _M_release(),
223  // destroy() must observe results of dispose()
224  __atomic_thread_fence (__ATOMIC_ACQ_REL);
225  }
226  _M_destroy();
227  }
228  }
229 
230  long
231  _M_get_use_count() const noexcept
232  {
233  // No memory barrier is used here so there is no synchronization
234  // with other threads.
235  auto __count = __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
236 
237  // If long is wider than _Atomic_word then we can treat _Atomic_word
238  // as unsigned, and so double its usable range. If the widths are the
239  // same then casting to unsigned and then to long is a no-op.
240  return static_cast<_Unsigned_count_type>(__count);
241  }
242 
243  private:
244  _Sp_counted_base(_Sp_counted_base const&) = delete;
245  _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
246 
247 #pragma GCC diagnostic push
248 #pragma GCC diagnostic ignored "-Wignored-attributes"
249  // This is only to be used for arithmetic, not for atomic ops.
250  using _Unsigned_count_type = make_unsigned<_Atomic_word>::type;
251 #pragma GCC diagnostic pop
252 
253  // Called when incrementing _M_use_count to cause a trap on overflow.
254  // This should be passed the value of the counter before the increment.
255  static void
256  _S_chk(_Atomic_word __count)
257  {
258  constexpr _Atomic_word __max_atomic_word = _Unsigned_count_type(-1)/2;
259 
260  // __max is the maximum allowed value for the shared reference count.
261  // All valid reference count values need to fit into [0,LONG_MAX)
262  // because users can observe the count via shared_ptr::use_count().
263  //
264  // When long is wider than _Atomic_word, _M_use_count can go negative
265  // and the cast in _Sp_counted_base::use_count() will turn it into a
266  // positive value suitable for returning to users. The implementation
267  // only cares whether _M_use_count reaches zero after a decrement,
268  // so negative values are not a problem internally.
269  // So when possible, use -1 for __max (incrementing past that would
270  // overflow _M_use_count to 0, which means an empty shared_ptr).
271  //
272  // When long is not wider than _Atomic_word, __max is just the type's
273  // maximum positive value. We cannot use negative counts because they
274  // would not fit in [0,LONG_MAX) after casting to an unsigned type,
275  // which would cause use_count() to return bogus values.
276  constexpr _Atomic_word __max
277  = sizeof(long) > sizeof(_Atomic_word) ? -1 : __max_atomic_word;
278 
279  if (__count == __max) [[__unlikely__]]
280  __builtin_trap();
281  }
282 
283  _Atomic_word _M_use_count; // #shared
284  _Atomic_word _M_weak_count; // #weak + (#shared != 0)
285  };
286 
287  // We use __atomic_add_single and __exchange_and_add_single in the _S_single
288  // member specializations because they use unsigned arithmetic and so avoid
289  // undefined overflow.
290  template<>
291  inline void
292  _Sp_counted_base<_S_single>::_M_add_ref_copy()
293  {
294  _S_chk(_M_use_count);
295  __gnu_cxx::__atomic_add_single(&_M_use_count, 1);
296  }
297 
298  template<>
299  inline void
300  _Sp_counted_base<_S_single>::_M_weak_release() noexcept
301  {
302  if (__gnu_cxx::__exchange_and_add_single(&_M_weak_count, -1) == 1)
303  _M_destroy();
304  }
305 
306  template<>
307  inline long
308  _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept
309  {
310  return static_cast<_Unsigned_count_type>(_M_use_count);
311  }
312 
313 
314  template<>
315  inline bool
316  _Sp_counted_base<_S_single>::
317  _M_add_ref_lock_nothrow() noexcept
318  {
319  if (_M_use_count == 0)
320  return false;
321  _M_add_ref_copy();
322  return true;
323  }
324 
325  template<>
326  inline bool
327  _Sp_counted_base<_S_mutex>::
328  _M_add_ref_lock_nothrow() noexcept
329  {
330  __gnu_cxx::__scoped_lock sentry(*this);
331  if (auto __c = __gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1))
332  _S_chk(__c);
333  else
334  {
335  // Count was zero, so we cannot lock it to get a shared_ptr.
336  // Reset to zero. This isn't racy, because there are no shared_ptr
337  // objects using this count and any other weak_ptr objects using it
338  // must call this function to modify _M_use_count, so would be
339  // synchronized by the mutex.
340  _M_use_count = 0;
341  return false;
342  }
343  return true;
344  }
345 
346  template<>
347  inline bool
348  _Sp_counted_base<_S_atomic>::
349  _M_add_ref_lock_nothrow() noexcept
350  {
351  // Perform lock-free add-if-not-zero operation.
352  _Atomic_word __count = _M_get_use_count();
353  do
354  {
355  if (__count == 0)
356  return false;
357  // Replace the current counter value with the old value + 1, as
358  // long as it's not changed meanwhile.
359  }
360  while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
361  true, __ATOMIC_ACQ_REL,
362  __ATOMIC_RELAXED));
363  _S_chk(__count);
364  return true;
365  }
366 
367  template<>
368  inline void
369  _Sp_counted_base<_S_single>::_M_release() noexcept
370  {
371  if (__gnu_cxx::__exchange_and_add_single(&_M_use_count, -1) == 1)
372  {
373  _M_dispose();
374  _M_weak_release();
375  }
376  }
377 
378  template<>
379  inline void
380  _Sp_counted_base<_S_mutex>::_M_release() noexcept
381  {
382  // Be race-detector-friendly. For more info see bits/c++config.
383  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
384  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
385  {
386  _M_release_last_use();
387  }
388  }
389 
390  template<>
391  inline void
392  _Sp_counted_base<_S_atomic>::_M_release() noexcept
393  {
394 #pragma GCC diagnostic push
395 #pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
396  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
397 #if ! _GLIBCXX_TSAN
398  constexpr bool __lock_free
399  = __atomic_always_lock_free(sizeof(long long), 0)
400  && __atomic_always_lock_free(sizeof(_Atomic_word), 0);
401  constexpr bool __double_word
402  = sizeof(long long) == 2 * sizeof(_Atomic_word);
403  // The ref-count members follow the vptr, so are aligned to
404  // alignof(void*).
405  constexpr bool __aligned = __alignof(long long) <= alignof(void*);
406  if constexpr (__lock_free && __double_word && __aligned)
407  {
408  constexpr int __wordbits = __CHAR_BIT__ * sizeof(_Atomic_word);
409  constexpr int __shiftbits = __double_word ? __wordbits : 0;
410  constexpr long long __unique_ref = 1LL + (1LL << __shiftbits);
411  auto __both_counts = reinterpret_cast<long long*>(&_M_use_count);
412 
413  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
414  if (__atomic_load_n(__both_counts, __ATOMIC_ACQUIRE) == __unique_ref)
415  {
416  // Both counts are 1, so there are no weak references and
417  // we are releasing the last strong reference. No other
418  // threads can observe the effects of this _M_release()
419  // call (e.g. calling use_count()) without a data race.
420  _M_weak_count = _M_use_count = 0;
421  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
422  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
423  _M_dispose();
424  _M_destroy();
425  return;
426  }
427  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
428  [[__unlikely__]]
429  {
430  _M_release_last_use_cold();
431  return;
432  }
433  }
434  else
435 #endif
436  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
437  {
438  _M_release_last_use();
439  }
440 #pragma GCC diagnostic pop
441  }
442 
443  // Forward declarations.
444  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
445  class __shared_ptr;
446 
447  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
448  class __weak_ptr;
449 
450  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
451  class __enable_shared_from_this;
452 
453  template<typename _Tp>
454  class shared_ptr;
455 
456  template<typename _Tp>
457  class weak_ptr;
458 
459  template<typename _Tp>
460  struct owner_less;
461 
462  template<typename _Tp>
463  class enable_shared_from_this;
464 
465  template<_Lock_policy _Lp = __default_lock_policy>
466  class __weak_count;
467 
468  template<_Lock_policy _Lp = __default_lock_policy>
469  class __shared_count;
470 
471 #ifdef __glibcxx_atomic_shared_ptr
472  template<typename>
473  class _Sp_atomic;
474 #endif
475 
476  // Counted ptr with no deleter or allocator support
477  template<typename _Ptr, _Lock_policy _Lp>
478  class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
479  {
480  public:
481  explicit
482  _Sp_counted_ptr(_Ptr __p) noexcept
483  : _M_ptr(__p) { }
484 
485  virtual void
486  _M_dispose() noexcept
487  { delete _M_ptr; }
488 
489  virtual void
490  _M_destroy() noexcept
491  { delete this; }
492 
493  virtual void*
494  _M_get_deleter(const std::type_info&) noexcept
495  { return nullptr; }
496 
497  _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
498  _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
499 
500  private:
501  _Ptr _M_ptr;
502  };
503 
504  template<>
505  inline void
506  _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { }
507 
508  template<>
509  inline void
510  _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { }
511 
512  template<>
513  inline void
514  _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { }
515 
516  // FIXME: once __has_cpp_attribute(__no_unique_address__)) is true for
517  // all supported compilers we can greatly simplify _Sp_ebo_helper.
518  // N.B. unconditionally applying the attribute could change layout for
519  // final types, which currently cannot use EBO so have a unique address.
520 
521  template<int _Nm, typename _Tp,
522  bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
523  struct _Sp_ebo_helper;
524 
525  /// Specialization using EBO.
526  template<int _Nm, typename _Tp>
527  struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp
528  {
529  explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { }
530  explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { }
531 
532  static _Tp&
533  _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); }
534  };
535 
536  /// Specialization not using EBO.
537  template<int _Nm, typename _Tp>
538  struct _Sp_ebo_helper<_Nm, _Tp, false>
539  {
540  explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { }
541  explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(std::move(__tp)) { }
542 
543  static _Tp&
544  _S_get(_Sp_ebo_helper& __eboh)
545  { return __eboh._M_tp; }
546 
547  private:
548  _Tp _M_tp;
549  };
550 
551  // Support for custom deleter and/or allocator
552  template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
553  class _Sp_counted_deleter final : public _Sp_counted_base<_Lp>
554  {
555  class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc>
556  {
557  typedef _Sp_ebo_helper<0, _Deleter> _Del_base;
558  typedef _Sp_ebo_helper<1, _Alloc> _Alloc_base;
559 
560  public:
561  _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
562  : _Del_base(std::move(__d)), _Alloc_base(__a), _M_ptr(__p)
563  { }
564 
565  _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); }
566  _Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); }
567 
568  _Ptr _M_ptr;
569  };
570 
571  public:
572  using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>;
573 
574  // __d(__p) must not throw.
575  _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
576  : _M_impl(__p, std::move(__d), _Alloc()) { }
577 
578  // __d(__p) must not throw.
579  _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
580  : _M_impl(__p, std::move(__d), __a) { }
581 
582 #pragma GCC diagnostic push // PR tree-optimization/122197
583 #pragma GCC diagnostic ignored "-Wfree-nonheap-object"
584 #pragma GCC diagnostic ignored "-Warray-bounds"
585  template<typename> class auto_ptr;
586  ~_Sp_counted_deleter() noexcept { }
587 
588  virtual void
589  _M_dispose() noexcept
590  { _M_impl._M_del()(_M_impl._M_ptr); }
591 #pragma GCC diagnostic pop
592 
593  virtual void
594  _M_destroy() noexcept
595  {
596  __allocator_type __a(_M_impl._M_alloc());
597  __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
598  this->~_Sp_counted_deleter();
599  }
600 
601  virtual void*
602  _M_get_deleter(const type_info& __ti [[__gnu__::__unused__]]) noexcept
603  {
604 #if __cpp_rtti
605  // _GLIBCXX_RESOLVE_LIB_DEFECTS
606  // 2400. shared_ptr's get_deleter() should use addressof()
607  return __ti == typeid(_Deleter)
608  ? std::__addressof(_M_impl._M_del())
609  : nullptr;
610 #else
611  return nullptr;
612 #endif
613  }
614 
615  private:
616 #ifdef __glibcxx_out_ptr
617  template<typename, typename, typename...> friend class out_ptr_t;
618 #endif
619  _Impl _M_impl;
620  };
621 
622  // helpers for make_shared / allocate_shared
623 
624  struct _Sp_make_shared_tag
625  {
626  private:
627  template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
628  friend class _Sp_counted_ptr_inplace;
629 
630  static const type_info&
631  _S_ti() noexcept _GLIBCXX_VISIBILITY(default)
632  {
633  alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { };
634  return reinterpret_cast<const type_info&>(__tag);
635  }
636 
637  static bool _S_eq(const type_info&) noexcept;
638  };
639 
640  template<typename _Alloc>
641  struct _Sp_alloc_shared_tag
642  {
643  const _Alloc& _M_a;
644  };
645 
646  template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
647  class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
648  {
649  class _Impl : _Sp_ebo_helper<0, _Alloc>
650  {
651  typedef _Sp_ebo_helper<0, _Alloc> _A_base;
652 
653  public:
654  explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { }
655 
656  _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); }
657 
658  __gnu_cxx::__aligned_buffer<__remove_cv_t<_Tp>> _M_storage;
659  };
660 
661  public:
662  using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
663 
664  // Alloc parameter is not a reference so doesn't alias anything in __args
665  template<typename... _Args>
666  _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
667  : _M_impl(__a)
668  {
669  // _GLIBCXX_RESOLVE_LIB_DEFECTS
670  // 2070. allocate_shared should use allocator_traits<A>::construct
672  std::forward<_Args>(__args)...); // might throw
673  }
674 
675 #pragma GCC diagnostic push // PR tree-optimization/122197
676 #pragma GCC diagnostic ignored "-Warray-bounds"
677  ~_Sp_counted_ptr_inplace() noexcept { }
678 
679  virtual void
680  _M_dispose() noexcept
681  {
682  allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
683  }
684 #pragma GCC diagnostic pop
685 
686  // Override because the allocator needs to know the dynamic type
687  virtual void
688  _M_destroy() noexcept
689  {
690  __allocator_type __a(_M_impl._M_alloc());
691  __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
692  this->~_Sp_counted_ptr_inplace();
693  }
694 
695  private:
696  friend class __shared_count<_Lp>; // To be able to call _M_ptr().
697 
698  // No longer used, but code compiled against old libstdc++ headers
699  // might still call it from __shared_ptr ctor to get the pointer out.
700  virtual void*
701  _M_get_deleter(const std::type_info& __ti) noexcept override
702  {
703  // Check for the fake type_info first, so we don't try to access it
704  // as a real type_info object. Otherwise, check if it's the real
705  // type_info for this class. With RTTI enabled we can check directly,
706  // or call a library function to do it.
707  if (&__ti == &_Sp_make_shared_tag::_S_ti()
708  ||
709 #if __cpp_rtti
710  __ti == typeid(_Sp_make_shared_tag)
711 #else
712  _Sp_make_shared_tag::_S_eq(__ti)
713 #endif
714  )
715  return _M_ptr();
716  return nullptr;
717  }
718 
719  __remove_cv_t<_Tp>*
720  _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
721 
722  _Impl _M_impl;
723  };
724 
725 #ifdef __glibcxx_smart_ptr_for_overwrite // C++ >= 20 && HOSTED
726  struct _Sp_overwrite_tag { };
727 
728  // Partial specialization used for make_shared_for_overwrite<non-array>().
729  // This partial specialization is used when the allocator's value type
730  // is the special _Sp_overwrite_tag type.
731 #if __cpp_concepts
732  template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
733  requires is_same_v<typename _Alloc::value_type, _Sp_overwrite_tag>
734  class _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> final
735 #else
736  template<typename _Tp, template<typename> class _Alloc, _Lock_policy _Lp>
737  class _Sp_counted_ptr_inplace<_Tp, _Alloc<_Sp_overwrite_tag>, _Lp> final
738 #endif
739  : public _Sp_counted_base<_Lp>
740  {
741  [[no_unique_address]] _Alloc _M_alloc;
742 
743  union {
744  remove_cv_t<_Tp> _M_obj;
745  char _M_unused;
746  };
747 
748  friend class __shared_count<_Lp>; // To be able to call _M_ptr().
749 
750  auto _M_ptr() noexcept { return std::__addressof(_M_obj); }
751 
752  public:
753  using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
754 
755  _Sp_counted_ptr_inplace(const _Alloc& __a)
756  : _M_alloc(__a)
757  {
758  ::new((void*)_M_ptr()) _Tp; // default-initialized, for overwrite.
759  }
760 
761  ~_Sp_counted_ptr_inplace() noexcept { }
762 
763  virtual void
764  _M_dispose() noexcept
765  {
766  _M_obj.~_Tp();
767  }
768 
769  // Override because the allocator needs to know the dynamic type
770  virtual void
771  _M_destroy() noexcept
772  {
773  using pointer = typename allocator_traits<__allocator_type>::pointer;
774  __allocator_type __a(_M_alloc);
775  auto __p = pointer_traits<pointer>::pointer_to(*this);
776  __allocated_ptr<__allocator_type> __guard_ptr{ __a, __p };
777  this->~_Sp_counted_ptr_inplace();
778  }
779 
780  void*
781  _M_get_deleter(const std::type_info&) noexcept override
782  { return nullptr; }
783  };
784 #endif // __glibcxx_smart_ptr_for_overwrite
785 
786 #if __glibcxx_shared_ptr_arrays >= 201707L // C++ >= 20 && HOSTED
787  struct _Sp_overwrite_tag;
788 
789  // For make_shared<T[]>, make_shared<T[N]>, allocate_shared<T[]> etc.
790  template<typename _Alloc>
791  struct _Sp_counted_array_base
792  {
793  [[no_unique_address]] _Alloc _M_alloc{};
794  size_t _M_n = 0;
795  bool _M_overwrite = false;
796 
798  _M_alloc_array(size_t __tail)
799  {
800  return allocator_traits<_Alloc>::allocate(_M_alloc, _M_n + __tail);
801  }
802 
803  void
804  _M_dealloc_array(typename allocator_traits<_Alloc>::pointer __p,
805  size_t __tail)
806  {
807  allocator_traits<_Alloc>::deallocate(_M_alloc, __p, _M_n + __tail);
808  }
809 
810  // Init the array elements
811  template<typename _Init>
812  void
813  _M_init(typename allocator_traits<_Alloc>::value_type* __p,
814  _Init __init)
815  {
816  using _Tp = remove_pointer_t<_Init>;
817  using _Up = typename allocator_traits<_Alloc>::value_type;
818 
819  if constexpr (is_same_v<_Init, _Sp_overwrite_tag>)
820  {
822  _M_overwrite = true;
823  }
824  else if (__init == nullptr)
825  std::__uninitialized_default_n_a(__p, _M_n, _M_alloc);
826  else if constexpr (!is_array_v<_Tp>)
827  std::__uninitialized_fill_n_a(__p, _M_n, *__init, _M_alloc);
828  else
829  {
830 #pragma GCC diagnostic push
831 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
832  struct _Iter
833  {
834  using value_type = _Up;
835  using difference_type = ptrdiff_t;
836  using pointer = const _Up*;
837  using reference = const _Up&;
838  using iterator_category = forward_iterator_tag;
839 
840  const _Up* _M_p;
841  size_t _M_len;
842  size_t _M_pos;
843 
844  _Iter& operator++() { ++_M_pos; return *this; }
845  _Iter operator++(int) { auto __i(*this); ++_M_pos; return __i; }
846 
847  reference operator*() const { return _M_p[_M_pos % _M_len]; }
848  pointer operator->() const { return _M_p + (_M_pos % _M_len); }
849 
850  bool operator==(const _Iter& __i) const
851  { return _M_pos == __i._M_pos; }
852  };
853 #pragma GCC diagnostic pop
854 
855  _Iter __first{_S_first_elem(__init), sizeof(_Tp) / sizeof(_Up)};
856  _Iter __last = __first;
857  __last._M_pos = _M_n;
858  std::__uninitialized_copy_a(__first, __last, __p, _M_alloc);
859  }
860  }
861 
862  protected:
863  // Destroy the array elements
864  void
865  _M_dispose_array(typename allocator_traits<_Alloc>::value_type* __p)
866  {
867  if (_M_overwrite)
868  std::destroy_n(__p, _M_n);
869  else
870  {
871  size_t __n = _M_n;
872  while (__n--)
873  allocator_traits<_Alloc>::destroy(_M_alloc, __p + __n);
874  }
875  }
876 
877  private:
878  template<typename _Tp>
879  static _Tp*
880  _S_first_elem(_Tp* __p) { return __p; }
881 
882  template<typename _Tp, size_t _Nm>
883  static auto
884  _S_first_elem(_Tp (*__p)[_Nm]) { return _S_first_elem(*__p); }
885  };
886 
887  // Control block for make_shared<T[]>, make_shared<T[N]> etc. that will be
888  // placed into unused memory at the end of the array.
889  template<typename _Alloc, _Lock_policy _Lp>
890  class _Sp_counted_array final
891  : public _Sp_counted_base<_Lp>, _Sp_counted_array_base<_Alloc>
892  {
893  using pointer = typename allocator_traits<_Alloc>::pointer;
894 
895  pointer _M_alloc_ptr;
896 
897  auto _M_ptr() const noexcept { return std::to_address(_M_alloc_ptr); }
898 
899  friend class __shared_count<_Lp>; // To be able to call _M_ptr().
900 
901  public:
902  _Sp_counted_array(const _Sp_counted_array_base<_Alloc>& __a,
903  pointer __p) noexcept
904  : _Sp_counted_array_base<_Alloc>(__a), _M_alloc_ptr(__p)
905  { }
906 
907  ~_Sp_counted_array() = default;
908 
909  virtual void
910  _M_dispose() noexcept
911  {
912  if (this->_M_n)
913  this->_M_dispose_array(_M_ptr());
914  }
915 
916  // Override because the allocator needs to know the dynamic type
917  virtual void
918  _M_destroy() noexcept
919  {
920  _Sp_counted_array_base<_Alloc> __a = *this;
921  pointer __p = _M_alloc_ptr;
922  this->~_Sp_counted_array();
923  __a._M_dealloc_array(__p, _S_tail());
924  }
925 
926  // Returns the number of additional array elements that must be
927  // allocated in order to store a _Sp_counted_array at the end.
928  static constexpr size_t
929  _S_tail()
930  {
931  // The array elemenent type.
932  using _Tp = typename allocator_traits<_Alloc>::value_type;
933 
934  // The space needed to store a _Sp_counted_array object.
935  size_t __bytes = sizeof(_Sp_counted_array);
936 
937  // Add any padding needed for manual alignment within the buffer.
938  if constexpr (alignof(_Tp) < alignof(_Sp_counted_array))
939  __bytes += alignof(_Sp_counted_array) - alignof(_Tp);
940 
941  return (__bytes + sizeof(_Tp) - 1) / sizeof(_Tp);
942  }
943 
944  void*
945  _M_get_deleter(const std::type_info&) noexcept override
946  { return nullptr; }
947  };
948 #endif // __glibcxx_shared_ptr_arrays >= 201707L
949 
950  // The default deleter for shared_ptr<T[]> and shared_ptr<T[N]>.
951  struct __sp_array_delete
952  {
953  template<typename _Yp>
954  void operator()(_Yp* __p) const { delete[] __p; }
955  };
956 
957  template<_Lock_policy _Lp>
958  class __shared_count
959  {
960  // Prevent _Sp_alloc_shared_tag from matching the shared_ptr(P, D) ctor.
961  template<typename _Tp>
962  struct __not_alloc_shared_tag { using type = void; };
963 
964  template<typename _Tp>
965  struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { };
966 
967 #if __glibcxx_shared_ptr_arrays >= 201707L // C++ >= 20 && HOSTED
968  template<typename _Alloc>
969  struct __not_alloc_shared_tag<_Sp_counted_array_base<_Alloc>> { };
970 #endif
971 
972  public:
973  constexpr __shared_count() noexcept : _M_pi(0)
974  { }
975 
976  template<typename _Ptr>
977  explicit
978  __shared_count(_Ptr __p) : _M_pi(0)
979  {
980  __try
981  {
982  _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
983  }
984  __catch(...)
985  {
986  delete __p;
987  __throw_exception_again;
988  }
989  }
990 
991  template<typename _Ptr>
992  __shared_count(_Ptr __p, /* is_array = */ false_type)
993  : __shared_count(__p)
994  { }
995 
996  template<typename _Ptr>
997  __shared_count(_Ptr __p, /* is_array = */ true_type)
998  : __shared_count(__p, __sp_array_delete{}, allocator<void>())
999  { }
1000 
1001  template<typename _Ptr, typename _Deleter,
1002  typename = typename __not_alloc_shared_tag<_Deleter>::type>
1003  __shared_count(_Ptr __p, _Deleter __d)
1004  : __shared_count(__p, std::move(__d), allocator<void>())
1005  { }
1006 
1007  template<typename _Ptr, typename _Deleter, typename _Alloc,
1008  typename = typename __not_alloc_shared_tag<_Deleter>::type>
1009  __shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
1010  {
1011  typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
1012  __try
1013  {
1014  typename _Sp_cd_type::__allocator_type __a2(__a);
1015  auto __guard = std::__allocate_guarded(__a2);
1016  _Sp_cd_type* __mem = __guard.get();
1017  ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a));
1018  _M_pi = __mem;
1019  __guard = nullptr;
1020  }
1021  __catch(...)
1022  {
1023  __d(__p); // Call _Deleter on __p.
1024  __throw_exception_again;
1025  }
1026  }
1027 
1028  template<typename _Tp, typename _Alloc, typename... _Args>
1029  __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a,
1030  _Args&&... __args)
1031  {
1032  using _Tp2 = __remove_cv_t<_Tp>;
1033  using _Sp_cp_type = _Sp_counted_ptr_inplace<_Tp2, _Alloc, _Lp>;
1034  typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
1035  auto __guard = std::__allocate_guarded(__a2);
1036  _Sp_cp_type* __mem = __guard.get();
1037  auto __pi = ::new (__mem)
1038  _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
1039  __guard = nullptr;
1040  _M_pi = __pi;
1041  __p = __pi->_M_ptr();
1042  }
1043 
1044 #if __glibcxx_shared_ptr_arrays >= 201707L // C++ >= 20 && HOSTED
1045  template<typename _Tp, typename _Alloc, typename _Init>
1046  __shared_count(_Tp*& __p, const _Sp_counted_array_base<_Alloc>& __a,
1047  _Init __init)
1048  {
1049  using _Up = remove_all_extents_t<_Tp>;
1050  static_assert(is_same_v<_Up, typename _Alloc::value_type>);
1051 
1052  using _Sp_ca_type = _Sp_counted_array<_Alloc, _Lp>;
1053  const size_t __tail = _Sp_ca_type::_S_tail();
1054 
1055  struct _Guarded_ptr : _Sp_counted_array_base<_Alloc>
1056  {
1057  typename allocator_traits<_Alloc>::pointer _M_ptr;
1058 
1059  _Guarded_ptr(_Sp_counted_array_base<_Alloc> __a)
1060  : _Sp_counted_array_base<_Alloc>(__a),
1061  _M_ptr(this->_M_alloc_array(_Sp_ca_type::_S_tail()))
1062  { }
1063 
1064  ~_Guarded_ptr()
1065  {
1066  if (_M_ptr)
1067  this->_M_dealloc_array(_M_ptr, _Sp_ca_type::_S_tail());
1068  }
1069  };
1070 
1071  _Guarded_ptr __guard{__a};
1072  _Up* const __raw = std::to_address(__guard._M_ptr);
1073  __guard._M_init(__raw, __init); // might throw
1074 
1075  void* __c = __raw + __a._M_n;
1076  if constexpr (alignof(_Up) < alignof(_Sp_ca_type))
1077  {
1078  size_t __space = sizeof(_Up) * __tail;
1079  __c = std::align(alignof(_Sp_ca_type), sizeof(_Sp_ca_type),
1080  __c, __space);
1081  }
1082  auto __pi = ::new(__c) _Sp_ca_type(__guard, __guard._M_ptr);
1083  __guard._M_ptr = nullptr;
1084  _M_pi = __pi;
1085  __p = reinterpret_cast<_Tp*>(__raw);
1086  }
1087 #endif
1088 
1089 #if _GLIBCXX_USE_DEPRECATED
1090 #pragma GCC diagnostic push
1091 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1092  // Special case for auto_ptr<_Tp> to provide the strong guarantee.
1093  template<typename _Tp>
1094  explicit
1095  __shared_count(std::auto_ptr<_Tp>&& __r);
1096 #pragma GCC diagnostic pop
1097 #endif
1098 
1099  // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
1100  template<typename _Tp, typename _Del>
1101  explicit
1102  __shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
1103  {
1104  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1105  // 2415. Inconsistency between unique_ptr and shared_ptr
1106  if (__r.get() == nullptr)
1107  return;
1108 
1109  using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
1110  using _Del2 = __conditional_t<is_reference<_Del>::value,
1111  reference_wrapper<typename remove_reference<_Del>::type>,
1112  _Del>;
1113  using _Sp_cd_type
1114  = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
1115  using _Alloc = allocator<_Sp_cd_type>;
1116  using _Alloc_traits = allocator_traits<_Alloc>;
1117  _Alloc __a;
1118  _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
1119  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1120  // 3548. shared_ptr construction from unique_ptr should move
1121  // (not copy) the deleter
1122  _Alloc_traits::construct(__a, __mem, __r.release(),
1123  std::forward<_Del>(__r.get_deleter()));
1124  _M_pi = __mem;
1125  }
1126 
1127  // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
1128  explicit __shared_count(const __weak_count<_Lp>& __r);
1129 
1130  // Does not throw if __r._M_get_use_count() == 0, caller must check.
1131  explicit
1132  __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept;
1133 
1134  ~__shared_count() noexcept
1135  {
1136  if (_M_pi != nullptr)
1137  _M_pi->_M_release();
1138  }
1139 
1140  __shared_count(const __shared_count& __r) noexcept
1141  : _M_pi(__r._M_pi)
1142  {
1143  if (_M_pi != nullptr)
1144  _M_pi->_M_add_ref_copy();
1145  }
1146 
1147  __shared_count&
1148  operator=(const __shared_count& __r) noexcept
1149  {
1150  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
1151  if (__tmp != _M_pi)
1152  {
1153  if (__tmp != nullptr)
1154  __tmp->_M_add_ref_copy();
1155  if (_M_pi != nullptr)
1156  _M_pi->_M_release();
1157  _M_pi = __tmp;
1158  }
1159  return *this;
1160  }
1161 
1162  void
1163  _M_swap(__shared_count& __r) noexcept
1164  {
1165  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
1166  __r._M_pi = _M_pi;
1167  _M_pi = __tmp;
1168  }
1169 
1170  long
1171  _M_get_use_count() const noexcept
1172  { return _M_pi ? _M_pi->_M_get_use_count() : 0; }
1173 
1174  bool
1175  _M_unique() const noexcept
1176  { return this->_M_get_use_count() == 1; }
1177 
1178  void*
1179  _M_get_deleter(const std::type_info& __ti) const noexcept
1180  { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; }
1181 
1182  bool
1183  _M_less(const __shared_count& __rhs) const noexcept
1184  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
1185 
1186  bool
1187  _M_less(const __weak_count<_Lp>& __rhs) const noexcept
1188  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
1189 
1190 #ifdef __glibcxx_smart_ptr_owner_equality // >= C++26
1191  size_t
1192  _M_owner_hash() const noexcept
1193  { return std::hash<_Sp_counted_base<_Lp>*>()(this->_M_pi); }
1194 #endif
1195 
1196  // Friend function injected into enclosing namespace and found by ADL
1197  friend inline bool
1198  operator==(const __shared_count& __a, const __shared_count& __b) noexcept
1199  { return __a._M_pi == __b._M_pi; }
1200 
1201  private:
1202  friend class __weak_count<_Lp>;
1203 #ifdef __glibcxx_atomic_shared_ptr
1204  template<typename> friend class _Sp_atomic;
1205 #endif
1206 #ifdef __glibcxx_out_ptr
1207  template<typename, typename, typename...> friend class out_ptr_t;
1208 #endif
1209 
1210  _Sp_counted_base<_Lp>* _M_pi;
1211  };
1212 
1213 
1214  template<_Lock_policy _Lp>
1215  class __weak_count
1216  {
1217  public:
1218  constexpr __weak_count() noexcept : _M_pi(nullptr)
1219  { }
1220 
1221  __weak_count(const __shared_count<_Lp>& __r) noexcept
1222  : _M_pi(__r._M_pi)
1223  {
1224  if (_M_pi != nullptr)
1225  _M_pi->_M_weak_add_ref();
1226  }
1227 
1228  __weak_count(const __weak_count& __r) noexcept
1229  : _M_pi(__r._M_pi)
1230  {
1231  if (_M_pi != nullptr)
1232  _M_pi->_M_weak_add_ref();
1233  }
1234 
1235  __weak_count(__weak_count&& __r) noexcept
1236  : _M_pi(__r._M_pi)
1237  { __r._M_pi = nullptr; }
1238 
1239  ~__weak_count() noexcept
1240  {
1241  if (_M_pi != nullptr)
1242  _M_pi->_M_weak_release();
1243  }
1244 
1245  __weak_count&
1246  operator=(const __shared_count<_Lp>& __r) noexcept
1247  {
1248  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
1249  if (__tmp != nullptr)
1250  __tmp->_M_weak_add_ref();
1251  if (_M_pi != nullptr)
1252  _M_pi->_M_weak_release();
1253  _M_pi = __tmp;
1254  return *this;
1255  }
1256 
1257  __weak_count&
1258  operator=(const __weak_count& __r) noexcept
1259  {
1260  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
1261  if (__tmp != nullptr)
1262  __tmp->_M_weak_add_ref();
1263  if (_M_pi != nullptr)
1264  _M_pi->_M_weak_release();
1265  _M_pi = __tmp;
1266  return *this;
1267  }
1268 
1269  __weak_count&
1270  operator=(__weak_count&& __r) noexcept
1271  {
1272  if (_M_pi != nullptr)
1273  _M_pi->_M_weak_release();
1274  _M_pi = __r._M_pi;
1275  __r._M_pi = nullptr;
1276  return *this;
1277  }
1278 
1279  void
1280  _M_swap(__weak_count& __r) noexcept
1281  {
1282  _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
1283  __r._M_pi = _M_pi;
1284  _M_pi = __tmp;
1285  }
1286 
1287  long
1288  _M_get_use_count() const noexcept
1289  { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
1290 
1291  bool
1292  _M_less(const __weak_count& __rhs) const noexcept
1293  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
1294 
1295  bool
1296  _M_less(const __shared_count<_Lp>& __rhs) const noexcept
1297  { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
1298 
1299 #ifdef __glibcxx_smart_ptr_owner_equality // >= C++26
1300  size_t
1301  _M_owner_hash() const noexcept
1302  { return std::hash<_Sp_counted_base<_Lp>*>()(this->_M_pi); }
1303 #endif
1304 
1305  // Friend function injected into enclosing namespace and found by ADL
1306  friend inline bool
1307  operator==(const __weak_count& __a, const __weak_count& __b) noexcept
1308  { return __a._M_pi == __b._M_pi; }
1309 
1310  private:
1311  friend class __shared_count<_Lp>;
1312 #ifdef __glibcxx_atomic_shared_ptr
1313  template<typename> friend class _Sp_atomic;
1314 #endif
1315 
1316  _Sp_counted_base<_Lp>* _M_pi;
1317  };
1318 
1319  // Now that __weak_count is defined we can define this constructor:
1320  template<_Lock_policy _Lp>
1321  inline
1322  __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
1323  : _M_pi(__r._M_pi)
1324  {
1325  if (_M_pi == nullptr || !_M_pi->_M_add_ref_lock_nothrow())
1326  __throw_bad_weak_ptr();
1327  }
1328 
1329  // Now that __weak_count is defined we can define this constructor:
1330  template<_Lock_policy _Lp>
1331  inline
1332  __shared_count<_Lp>::
1333  __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept
1334  : _M_pi(__r._M_pi)
1335  {
1336  if (_M_pi && !_M_pi->_M_add_ref_lock_nothrow())
1337  _M_pi = nullptr;
1338  }
1339 
1340  // Helper traits for shared_ptr of array:
1341 
1342  // A pointer type Y* is said to be compatible with a pointer type T* when
1343  // either Y* is convertible to T* or Y is U[N] and T is U cv [].
1344  template<typename _Yp_ptr, typename _Tp_ptr>
1345  struct __sp_compatible_with
1346  : false_type
1347  { };
1348 
1349  template<typename _Yp, typename _Tp>
1350  struct __sp_compatible_with<_Yp*, _Tp*>
1351  : is_convertible<_Yp*, _Tp*>::type
1352  { };
1353 
1354  template<typename _Up, size_t _Nm>
1355  struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]>
1356  : true_type
1357  { };
1358 
1359  template<typename _Up, size_t _Nm>
1360  struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]>
1361  : true_type
1362  { };
1363 
1364  template<typename _Up, size_t _Nm>
1365  struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]>
1366  : true_type
1367  { };
1368 
1369  template<typename _Up, size_t _Nm>
1370  struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]>
1371  : true_type
1372  { };
1373 
1374  // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N].
1375  template<typename _Up, size_t _Nm, typename _Yp, typename = void>
1376  struct __sp_is_constructible_arrN
1377  : false_type
1378  { };
1379 
1380  template<typename _Up, size_t _Nm, typename _Yp>
1381  struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
1382  : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
1383  { };
1384 
1385  // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[].
1386  template<typename _Up, typename _Yp, typename = void>
1387  struct __sp_is_constructible_arr
1388  : false_type
1389  { };
1390 
1391  template<typename _Up, typename _Yp>
1392  struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
1393  : is_convertible<_Yp(*)[], _Up(*)[]>::type
1394  { };
1395 
1396  // Trait to check if shared_ptr<T> can be constructed from Y*.
1397  template<typename _Tp, typename _Yp>
1398  struct __sp_is_constructible;
1399 
1400  // When T is U[N], Y(*)[N] shall be convertible to T*;
1401  template<typename _Up, size_t _Nm, typename _Yp>
1402  struct __sp_is_constructible<_Up[_Nm], _Yp>
1403  : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
1404  { };
1405 
1406  // when T is U[], Y(*)[] shall be convertible to T*;
1407  template<typename _Up, typename _Yp>
1408  struct __sp_is_constructible<_Up[], _Yp>
1409  : __sp_is_constructible_arr<_Up, _Yp>::type
1410  { };
1411 
1412  // otherwise, Y* shall be convertible to T*.
1413  template<typename _Tp, typename _Yp>
1414  struct __sp_is_constructible
1415  : is_convertible<_Yp*, _Tp*>::type
1416  { };
1417 
1418 
1419  template<typename _Tp>
1420  [[__gnu__::__always_inline__]]
1421  inline _Tp*
1422  __shared_ptr_deref(_Tp* __p)
1423  {
1424  __glibcxx_assert(__p != nullptr);
1425  return __p;
1426  }
1427 
1428  // Define operator* and operator-> for shared_ptr<T>.
1429  template<typename _Tp, _Lock_policy _Lp,
1430  bool = is_array<_Tp>::value, bool = is_void<_Tp>::value>
1431  class __shared_ptr_access
1432  {
1433  public:
1434  using element_type = _Tp;
1435 
1436  element_type&
1437  operator*() const noexcept
1438  { return *std::__shared_ptr_deref(_M_get()); }
1439 
1440  element_type*
1441  operator->() const noexcept
1442  {
1443  _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
1444  return _M_get();
1445  }
1446 
1447  private:
1448  element_type*
1449  _M_get() const noexcept
1450  { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
1451  };
1452 
1453  // Define operator-> for shared_ptr<cv void>.
1454  template<typename _Tp, _Lock_policy _Lp>
1455  class __shared_ptr_access<_Tp, _Lp, false, true>
1456  {
1457  public:
1458  using element_type = _Tp;
1459 
1460  element_type*
1461  operator->() const noexcept
1462  {
1463  auto __ptr = static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get();
1464  _GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr);
1465  return __ptr;
1466  }
1467  };
1468 
1469  // Define operator[] for shared_ptr<T[]> and shared_ptr<T[N]>.
1470  template<typename _Tp, _Lock_policy _Lp>
1471  class __shared_ptr_access<_Tp, _Lp, true, false>
1472  {
1473  public:
1474  using element_type = typename remove_extent<_Tp>::type;
1475 
1476 #if __cplusplus <= 201402L
1477  [[__deprecated__("shared_ptr<T[]>::operator* is absent from C++17")]]
1478  element_type&
1479  operator*() const noexcept
1480  { return *std::__shared_ptr_deref(_M_get()); }
1481 
1482  [[__deprecated__("shared_ptr<T[]>::operator-> is absent from C++17")]]
1483  element_type*
1484  operator->() const noexcept
1485  {
1486  _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
1487  return _M_get();
1488  }
1489 #endif
1490 
1491 #pragma GCC diagnostic push
1492 #pragma GCC diagnostic ignored "-Wc++17-extensions"
1493  element_type&
1494  operator[](ptrdiff_t __i) const noexcept
1495  {
1496  if constexpr (extent<_Tp>::value)
1497  __glibcxx_assert(__i < extent<_Tp>::value);
1498  return std::__shared_ptr_deref(_M_get())[__i];
1499  }
1500 #pragma GCC diagnostic pop
1501 
1502  private:
1503  element_type*
1504  _M_get() const noexcept
1505  { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
1506  };
1507 
1508  template<typename _Tp, _Lock_policy _Lp>
1509  class __shared_ptr
1510  : public __shared_ptr_access<_Tp, _Lp>
1511  {
1512  public:
1513  using element_type = typename remove_extent<_Tp>::type;
1514 
1515  private:
1516  // Constraint for taking ownership of a pointer of type _Yp*:
1517  template<typename _Yp>
1518  using _SafeConv
1519  = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type;
1520 
1521  // Constraint for construction from shared_ptr and weak_ptr:
1522  template<typename _Yp, typename _Res = void>
1523  using _Compatible = typename
1524  enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
1525 
1526  // Constraint for assignment from shared_ptr and weak_ptr:
1527  template<typename _Yp>
1528  using _Assignable = _Compatible<_Yp, __shared_ptr&>;
1529 
1530  // Constraint for construction from unique_ptr:
1531  template<typename _Yp, typename _Del, typename _Res = void,
1532  typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer>
1533  using _UniqCompatible = __enable_if_t<__and_<
1534  __sp_compatible_with<_Yp*, _Tp*>,
1535  is_convertible<_Ptr, element_type*>,
1536  is_move_constructible<_Del>
1537  >::value, _Res>;
1538 
1539  // Constraint for assignment from unique_ptr:
1540  template<typename _Yp, typename _Del>
1541  using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>;
1542 
1543  public:
1544 
1545 #if __cplusplus > 201402L
1546  using weak_type = __weak_ptr<_Tp, _Lp>;
1547 #endif
1548 
1549  constexpr __shared_ptr() noexcept
1550  : _M_ptr(0), _M_refcount()
1551  { }
1552 
1553  template<typename _Yp, typename = _SafeConv<_Yp>>
1554  explicit
1555  __shared_ptr(_Yp* __p)
1556  : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type())
1557  {
1558  static_assert( !is_void<_Yp>::value, "incomplete type" );
1559  static_assert( sizeof(_Yp) > 0, "incomplete type" );
1560  _M_enable_shared_from_this_with(__p);
1561  }
1562 
1563  template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>>
1564  __shared_ptr(_Yp* __p, _Deleter __d)
1565  : _M_ptr(__p), _M_refcount(__p, std::move(__d))
1566  {
1567  static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1568  "deleter expression d(p) is well-formed");
1569  _M_enable_shared_from_this_with(__p);
1570  }
1571 
1572  template<typename _Yp, typename _Deleter, typename _Alloc,
1573  typename = _SafeConv<_Yp>>
1574  __shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
1575  : _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a))
1576  {
1577  static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1578  "deleter expression d(p) is well-formed");
1579  _M_enable_shared_from_this_with(__p);
1580  }
1581 
1582  template<typename _Deleter>
1583  __shared_ptr(nullptr_t __p, _Deleter __d)
1584  : _M_ptr(0), _M_refcount(__p, std::move(__d))
1585  { }
1586 
1587  template<typename _Deleter, typename _Alloc>
1588  __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
1589  : _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a))
1590  { }
1591 
1592  // Aliasing constructor
1593  template<typename _Yp>
1594  __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r,
1595  element_type* __p) noexcept
1596  : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
1597  { }
1598 
1599  // Aliasing constructor
1600  template<typename _Yp>
1601  __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r,
1602  element_type* __p) noexcept
1603  : _M_ptr(__p), _M_refcount()
1604  {
1605  _M_refcount._M_swap(__r._M_refcount);
1606  __r._M_ptr = nullptr;
1607  }
1608 
1609  __shared_ptr(const __shared_ptr&) noexcept = default;
1610  __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
1611  ~__shared_ptr() = default;
1612 
1613  template<typename _Yp, typename = _Compatible<_Yp>>
1614  __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1615  : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1616  { }
1617 
1618  __shared_ptr(__shared_ptr&& __r) noexcept
1619  : _M_ptr(__r._M_ptr), _M_refcount()
1620  {
1621  _M_refcount._M_swap(__r._M_refcount);
1622  __r._M_ptr = nullptr;
1623  }
1624 
1625  template<typename _Yp, typename = _Compatible<_Yp>>
1626  __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1627  : _M_ptr(__r._M_ptr), _M_refcount()
1628  {
1629  _M_refcount._M_swap(__r._M_refcount);
1630  __r._M_ptr = nullptr;
1631  }
1632 
1633  template<typename _Yp, typename = _Compatible<_Yp>>
1634  explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r)
1635  : _M_refcount(__r._M_refcount) // may throw
1636  {
1637  // It is now safe to copy __r._M_ptr, as
1638  // _M_refcount(__r._M_refcount) did not throw.
1639  _M_ptr = __r._M_ptr;
1640  }
1641 
1642  // If an exception is thrown this constructor has no effect.
1643  template<typename _Yp, typename _Del,
1644  typename = _UniqCompatible<_Yp, _Del>>
1645  __shared_ptr(unique_ptr<_Yp, _Del>&& __r)
1646  : _M_ptr(__r.get()), _M_refcount()
1647  {
1648  auto __raw = std::__to_address(__r.get());
1649  _M_refcount = __shared_count<_Lp>(std::move(__r));
1650  _M_enable_shared_from_this_with(__raw);
1651  }
1652 
1653 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
1654  protected:
1655  // If an exception is thrown this constructor has no effect.
1656  template<typename _Tp1, typename _Del,
1657  typename enable_if<__and_<
1658  __not_<is_array<_Tp>>, is_array<_Tp1>,
1659  is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*>
1660  >::value, bool>::type = true>
1661  __shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete)
1662  : _M_ptr(__r.get()), _M_refcount()
1663  {
1664  auto __raw = std::__to_address(__r.get());
1665  _M_refcount = __shared_count<_Lp>(std::move(__r));
1666  _M_enable_shared_from_this_with(__raw);
1667  }
1668  public:
1669 #endif
1670 
1671 #if _GLIBCXX_USE_DEPRECATED
1672 #pragma GCC diagnostic push
1673 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1674  // Postcondition: use_count() == 1 and __r.get() == 0
1675  template<typename _Yp, typename = _Compatible<_Yp>>
1676  __shared_ptr(auto_ptr<_Yp>&& __r);
1677 #pragma GCC diagnostic pop
1678 #endif
1679 
1680  constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
1681 
1682  template<typename _Yp>
1683  _Assignable<_Yp>
1684  operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1685  {
1686  _M_ptr = __r._M_ptr;
1687  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
1688  return *this;
1689  }
1690 
1691 #if _GLIBCXX_USE_DEPRECATED
1692 #pragma GCC diagnostic push
1693 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1694  template<typename _Yp>
1695  _Assignable<_Yp>
1696  operator=(auto_ptr<_Yp>&& __r)
1697  {
1698  __shared_ptr(std::move(__r)).swap(*this);
1699  return *this;
1700  }
1701 #pragma GCC diagnostic pop
1702 #endif
1703 
1704  __shared_ptr&
1705  operator=(__shared_ptr&& __r) noexcept
1706  {
1707  __shared_ptr(std::move(__r)).swap(*this);
1708  return *this;
1709  }
1710 
1711  template<class _Yp>
1712  _Assignable<_Yp>
1713  operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1714  {
1715  __shared_ptr(std::move(__r)).swap(*this);
1716  return *this;
1717  }
1718 
1719  template<typename _Yp, typename _Del>
1720  _UniqAssignable<_Yp, _Del>
1721  operator=(unique_ptr<_Yp, _Del>&& __r)
1722  {
1723  __shared_ptr(std::move(__r)).swap(*this);
1724  return *this;
1725  }
1726 
1727  void
1728  reset() noexcept
1729  { __shared_ptr().swap(*this); }
1730 
1731  template<typename _Yp>
1732  _SafeConv<_Yp>
1733  reset(_Yp* __p) // _Yp must be complete.
1734  {
1735  // Catch self-reset errors.
1736  __glibcxx_assert(__p == nullptr || __p != _M_ptr);
1737  __shared_ptr(__p).swap(*this);
1738  }
1739 
1740  template<typename _Yp, typename _Deleter>
1741  _SafeConv<_Yp>
1742  reset(_Yp* __p, _Deleter __d)
1743  { __shared_ptr(__p, std::move(__d)).swap(*this); }
1744 
1745  template<typename _Yp, typename _Deleter, typename _Alloc>
1746  _SafeConv<_Yp>
1747  reset(_Yp* __p, _Deleter __d, _Alloc __a)
1748  { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); }
1749 
1750  /// Return the stored pointer.
1751  element_type*
1752  get() const noexcept
1753  { return _M_ptr; }
1754 
1755  /// Return true if the stored pointer is not null.
1756  explicit operator bool() const noexcept
1757  { return _M_ptr != nullptr; }
1758 
1759  /// Return true if use_count() == 1.
1760  bool
1761  unique() const noexcept
1762  { return _M_refcount._M_unique(); }
1763 
1764  /// If *this owns a pointer, return the number of owners, otherwise zero.
1765  long
1766  use_count() const noexcept
1767  { return _M_refcount._M_get_use_count(); }
1768 
1769  /// Exchange both the owned pointer and the stored pointer.
1770  void
1771  swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
1772  {
1773  std::swap(_M_ptr, __other._M_ptr);
1774  _M_refcount._M_swap(__other._M_refcount);
1775  }
1776 
1777  /** @brief Define an ordering based on ownership.
1778  *
1779  * This function defines a strict weak ordering between two shared_ptr
1780  * or weak_ptr objects, such that one object is less than the other
1781  * unless they share ownership of the same pointer, or are both empty.
1782  * @{
1783  */
1784  template<typename _Tp1>
1785  bool
1786  owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1787  { return _M_refcount._M_less(__rhs._M_refcount); }
1788 
1789  template<typename _Tp1>
1790  bool
1791  owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1792  { return _M_refcount._M_less(__rhs._M_refcount); }
1793  /// @}
1794 
1795 #ifdef __glibcxx_smart_ptr_owner_equality // >= C++26
1796  size_t owner_hash() const noexcept { return _M_refcount._M_owner_hash(); }
1797 
1798  template<typename _Tp1>
1799  bool
1800  owner_equal(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1801  { return _M_refcount == __rhs._M_refcount; }
1802 
1803  template<typename _Tp1>
1804  bool
1805  owner_equal(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1806  { return _M_refcount == __rhs._M_refcount; }
1807 #endif
1808 
1809  protected:
1810  // This constructor is non-standard, it is used by allocate_shared.
1811  template<typename _Alloc, typename... _Args>
1812  __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
1813  : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
1814  { _M_enable_shared_from_this_with(_M_ptr); }
1815 
1816  template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
1817  typename... _Args>
1818  friend __shared_ptr<_Tp1, _Lp1>
1819  __allocate_shared(const _Alloc& __a, _Args&&... __args);
1820 
1821 #if __glibcxx_shared_ptr_arrays >= 201707L // C++ >= 20 && HOSTED
1822  // This constructor is non-standard, it is used by allocate_shared<T[]>.
1823  template<typename _Alloc, typename _Init = const remove_extent_t<_Tp>*>
1824  __shared_ptr(const _Sp_counted_array_base<_Alloc>& __a,
1825  _Init __init = nullptr)
1826  : _M_ptr(), _M_refcount(_M_ptr, __a, __init)
1827  { }
1828 #endif
1829 
1830  // This constructor is used by __weak_ptr::lock() and
1831  // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
1832  __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) noexcept
1833  : _M_refcount(__r._M_refcount, std::nothrow)
1834  {
1835  _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr;
1836  }
1837 
1838  friend class __weak_ptr<_Tp, _Lp>;
1839 
1840  private:
1841 
1842  template<typename _Yp>
1843  using __esft_base_t = decltype(__enable_shared_from_this_base(
1844  std::declval<const __shared_count<_Lp>&>(),
1845  std::declval<_Yp*>()));
1846 
1847  // Detect an accessible and unambiguous enable_shared_from_this base.
1848  template<typename _Yp, typename = void>
1849  struct __has_esft_base
1850  : false_type { };
1851 
1852  template<typename _Yp>
1853  struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
1854  : __not_<is_array<_Tp>> { }; // No enable shared_from_this for arrays
1855 
1856  template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1857  typename enable_if<__has_esft_base<_Yp2>::value>::type
1858  _M_enable_shared_from_this_with(_Yp* __p) noexcept
1859  {
1860  if (auto __base = __enable_shared_from_this_base(_M_refcount, __p))
1861  __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount);
1862  }
1863 
1864  template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1865  typename enable_if<!__has_esft_base<_Yp2>::value>::type
1866  _M_enable_shared_from_this_with(_Yp*) noexcept
1867  { }
1868 
1869  void*
1870  _M_get_deleter(const std::type_info& __ti) const noexcept
1871  { return _M_refcount._M_get_deleter(__ti); }
1872 
1873  template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1874  template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1875 
1876  template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
1877  friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
1878 
1879  template<typename _Del, typename _Tp1>
1880  friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept;
1881 
1882 #ifdef __glibcxx_atomic_shared_ptr
1883  friend _Sp_atomic<shared_ptr<_Tp>>;
1884 #endif
1885 #ifdef __glibcxx_out_ptr
1886  template<typename, typename, typename...> friend class out_ptr_t;
1887 #endif
1888 
1889  element_type* _M_ptr; // Contained pointer.
1890  __shared_count<_Lp> _M_refcount; // Reference counter.
1891  };
1892 
1893 
1894  // 20.7.2.2.7 shared_ptr comparisons
1895  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1896  inline bool
1897  operator==(const __shared_ptr<_Tp1, _Lp>& __a,
1898  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1899  { return __a.get() == __b.get(); }
1900 
1901  template<typename _Tp, _Lock_policy _Lp>
1902  inline bool
1903  operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1904  { return !__a; }
1905 
1906 #ifdef __cpp_lib_three_way_comparison
1907  template<typename _Tp, typename _Up, _Lock_policy _Lp>
1908  inline strong_ordering
1909  operator<=>(const __shared_ptr<_Tp, _Lp>& __a,
1910  const __shared_ptr<_Up, _Lp>& __b) noexcept
1911  { return compare_three_way()(__a.get(), __b.get()); }
1912 
1913  template<typename _Tp, _Lock_policy _Lp>
1914  inline strong_ordering
1915  operator<=>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1916  {
1917  using pointer = typename __shared_ptr<_Tp, _Lp>::element_type*;
1918  return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
1919  }
1920 #else
1921  template<typename _Tp, _Lock_policy _Lp>
1922  inline bool
1923  operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1924  { return !__a; }
1925 
1926  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1927  inline bool
1928  operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
1929  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1930  { return __a.get() != __b.get(); }
1931 
1932  template<typename _Tp, _Lock_policy _Lp>
1933  inline bool
1934  operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1935  { return (bool)__a; }
1936 
1937  template<typename _Tp, _Lock_policy _Lp>
1938  inline bool
1939  operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1940  { return (bool)__a; }
1941 
1942  template<typename _Tp, typename _Up, _Lock_policy _Lp>
1943  inline bool
1944  operator<(const __shared_ptr<_Tp, _Lp>& __a,
1945  const __shared_ptr<_Up, _Lp>& __b) noexcept
1946  {
1947  using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1948  using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type;
1949  using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
1950  return less<_Vp>()(__a.get(), __b.get());
1951  }
1952 
1953  template<typename _Tp, _Lock_policy _Lp>
1954  inline bool
1955  operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1956  {
1957  using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1958  return less<_Tp_elt*>()(__a.get(), nullptr);
1959  }
1960 
1961  template<typename _Tp, _Lock_policy _Lp>
1962  inline bool
1963  operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1964  {
1965  using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1966  return less<_Tp_elt*>()(nullptr, __a.get());
1967  }
1968 
1969  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1970  inline bool
1971  operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
1972  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1973  { return !(__b < __a); }
1974 
1975  template<typename _Tp, _Lock_policy _Lp>
1976  inline bool
1977  operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1978  { return !(nullptr < __a); }
1979 
1980  template<typename _Tp, _Lock_policy _Lp>
1981  inline bool
1982  operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1983  { return !(__a < nullptr); }
1984 
1985  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1986  inline bool
1987  operator>(const __shared_ptr<_Tp1, _Lp>& __a,
1988  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1989  { return (__b < __a); }
1990 
1991  template<typename _Tp, _Lock_policy _Lp>
1992  inline bool
1993  operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1994  { return nullptr < __a; }
1995 
1996  template<typename _Tp, _Lock_policy _Lp>
1997  inline bool
1998  operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1999  { return __a < nullptr; }
2000 
2001  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
2002  inline bool
2003  operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
2004  const __shared_ptr<_Tp2, _Lp>& __b) noexcept
2005  { return !(__a < __b); }
2006 
2007  template<typename _Tp, _Lock_policy _Lp>
2008  inline bool
2009  operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
2010  { return !(__a < nullptr); }
2011 
2012  template<typename _Tp, _Lock_policy _Lp>
2013  inline bool
2014  operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
2015  { return !(nullptr < __a); }
2016 #endif // three-way comparison
2017 
2018  // 20.7.2.2.8 shared_ptr specialized algorithms.
2019  template<typename _Tp, _Lock_policy _Lp>
2020  inline void
2021  swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
2022  { __a.swap(__b); }
2023 
2024  // 20.7.2.2.9 shared_ptr casts
2025 
2026  // The seemingly equivalent code:
2027  // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
2028  // will eventually result in undefined behaviour, attempting to
2029  // delete the same object twice.
2030  /// static_pointer_cast
2031  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
2032  inline __shared_ptr<_Tp, _Lp>
2033  static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
2034  {
2035  using _Sp = __shared_ptr<_Tp, _Lp>;
2036  return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
2037  }
2038 
2039  // The seemingly equivalent code:
2040  // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
2041  // will eventually result in undefined behaviour, attempting to
2042  // delete the same object twice.
2043  /// const_pointer_cast
2044  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
2045  inline __shared_ptr<_Tp, _Lp>
2046  const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
2047  {
2048  using _Sp = __shared_ptr<_Tp, _Lp>;
2049  return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
2050  }
2051 
2052  // The seemingly equivalent code:
2053  // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
2054  // will eventually result in undefined behaviour, attempting to
2055  // delete the same object twice.
2056  /// dynamic_pointer_cast
2057  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
2058  inline __shared_ptr<_Tp, _Lp>
2059  dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
2060  {
2061  using _Sp = __shared_ptr<_Tp, _Lp>;
2062  if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
2063  return _Sp(__r, __p);
2064  return _Sp();
2065  }
2066 
2067 #if __cplusplus > 201402L
2068  template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
2069  inline __shared_ptr<_Tp, _Lp>
2070  reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
2071  {
2072  using _Sp = __shared_ptr<_Tp, _Lp>;
2073  return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
2074  }
2075 #endif
2076 
2077  template<typename _Tp, _Lock_policy _Lp>
2078  class __weak_ptr
2079  {
2080  public:
2081  using element_type = typename remove_extent<_Tp>::type;
2082 
2083  private:
2084  template<typename _Yp, typename _Res = void>
2085  using _Compatible = typename
2086  enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
2087 
2088  // Constraint for assignment from shared_ptr and weak_ptr:
2089  template<typename _Yp>
2090  using _Assignable = _Compatible<_Yp, __weak_ptr&>;
2091 
2092 #pragma GCC diagnostic push
2093 #pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
2094  // Helper for construction/assignment:
2095  template<typename _Yp>
2096  static element_type*
2097  _S_safe_upcast(const __weak_ptr<_Yp, _Lp>& __r)
2098  {
2099  // We know that _Yp and _Tp are compatible, that is, either
2100  // _Yp* is convertible to _Tp* or _Yp is U[N] and _Tp is U cv [].
2101 
2102  // If _Yp is the same as _Tp after removing extents and cv
2103  // qualifications, there's no pointer adjustments to do. This
2104  // also allows us to support incomplete types.
2105  using _At = typename remove_cv<typename remove_extent<_Tp>::type>::type;
2106  using _Bt = typename remove_cv<typename remove_extent<_Yp>::type>::type;
2107  if constexpr (is_same<_At, _Bt>::value)
2108  return __r._M_ptr;
2109  // If they're not the same type, but they're both scalars,
2110  // we again don't need any adjustment. This allows us to support e.g.
2111  // pointers to a differently cv qualified type X.
2112  else if constexpr (__and_<is_scalar<_At>, is_scalar<_Bt>>::value)
2113  return __r._M_ptr;
2114 #if _GLIBCXX_USE_BUILTIN_TRAIT(__builtin_is_virtual_base_of)
2115  // If _Tp is not a virtual base class of _Yp, the pointer
2116  // conversion does not require dereferencing __r._M_ptr; just
2117  // rely on the implicit conversion.
2118  else if constexpr (!__builtin_is_virtual_base_of(_Tp, _Yp))
2119  return __r._M_ptr;
2120 #endif
2121  // Expensive path; must lock() and do the pointer conversion while
2122  // a shared_ptr keeps the pointee alive (because we may need
2123  // to dereference).
2124  else
2125  return __r.lock().get();
2126  }
2127 #pragma GCC diagnostic pop
2128 
2129  public:
2130  constexpr __weak_ptr() noexcept
2131  : _M_ptr(nullptr), _M_refcount()
2132  { }
2133 
2134  __weak_ptr(const __weak_ptr&) noexcept = default;
2135 
2136  ~__weak_ptr() = default;
2137 
2138  // The "obvious" converting constructor implementation:
2139  //
2140  // template<typename _Tp1>
2141  // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
2142  // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
2143  // { }
2144  //
2145  // has a serious problem.
2146  //
2147  // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
2148  // conversion may require access to *__r._M_ptr (virtual inheritance).
2149  //
2150  // It is not possible to avoid spurious access violations since
2151  // in multithreaded programs __r._M_ptr may be invalidated at any point.
2152  template<typename _Yp, typename = _Compatible<_Yp>>
2153  __weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept
2154  : _M_ptr(_S_safe_upcast(__r)), _M_refcount(__r._M_refcount)
2155  { }
2156 
2157  template<typename _Yp, typename = _Compatible<_Yp>>
2158  __weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
2159  : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
2160  { }
2161 
2162  __weak_ptr(__weak_ptr&& __r) noexcept
2163  : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
2164  { __r._M_ptr = nullptr; }
2165 
2166  template<typename _Yp, typename = _Compatible<_Yp>>
2167  __weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept
2168  : _M_ptr(_S_safe_upcast(__r)), _M_refcount(std::move(__r._M_refcount))
2169  { __r._M_ptr = nullptr; }
2170 
2171  __weak_ptr&
2172  operator=(const __weak_ptr& __r) noexcept = default;
2173 
2174  template<typename _Yp>
2175  _Assignable<_Yp>
2176  operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept
2177  {
2178  _M_ptr = _S_safe_upcast(__r);
2179  _M_refcount = __r._M_refcount;
2180  return *this;
2181  }
2182 
2183  template<typename _Yp>
2184  _Assignable<_Yp>
2185  operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
2186  {
2187  _M_ptr = __r._M_ptr;
2188  _M_refcount = __r._M_refcount;
2189  return *this;
2190  }
2191 
2192  __weak_ptr&
2193  operator=(__weak_ptr&& __r) noexcept
2194  {
2195  __weak_ptr(std::move(__r)).swap(*this);
2196  return *this;
2197  }
2198 
2199  template<typename _Yp>
2200  _Assignable<_Yp>
2201  operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept
2202  {
2203  _M_ptr = _S_safe_upcast(__r);
2204  _M_refcount = std::move(__r._M_refcount);
2205  __r._M_ptr = nullptr;
2206  return *this;
2207  }
2208 
2209  __shared_ptr<_Tp, _Lp>
2210  lock() const noexcept
2211  { return __shared_ptr<_Tp, _Lp>(*this, std::nothrow); }
2212 
2213  long
2214  use_count() const noexcept
2215  { return _M_refcount._M_get_use_count(); }
2216 
2217  bool
2218  expired() const noexcept
2219  { return _M_refcount._M_get_use_count() == 0; }
2220 
2221  template<typename _Tp1>
2222  bool
2223  owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept
2224  { return _M_refcount._M_less(__rhs._M_refcount); }
2225 
2226  template<typename _Tp1>
2227  bool
2228  owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept
2229  { return _M_refcount._M_less(__rhs._M_refcount); }
2230 
2231 #ifdef __glibcxx_smart_ptr_owner_equality // >= C++26
2232  size_t owner_hash() const noexcept { return _M_refcount._M_owner_hash(); }
2233 
2234  template<typename _Tp1>
2235  bool
2236  owner_equal(const __shared_ptr<_Tp1, _Lp> & __rhs) const noexcept
2237  { return _M_refcount == __rhs._M_refcount; }
2238 
2239  template<typename _Tp1>
2240  bool
2241  owner_equal(const __weak_ptr<_Tp1, _Lp> & __rhs) const noexcept
2242  { return _M_refcount == __rhs._M_refcount; }
2243 #endif
2244 
2245  void
2246  reset() noexcept
2247  { __weak_ptr().swap(*this); }
2248 
2249  void
2250  swap(__weak_ptr& __s) noexcept
2251  {
2252  std::swap(_M_ptr, __s._M_ptr);
2253  _M_refcount._M_swap(__s._M_refcount);
2254  }
2255 
2256  private:
2257  // Used by __enable_shared_from_this.
2258  void
2259  _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
2260  {
2261  if (use_count() == 0)
2262  {
2263  _M_ptr = __ptr;
2264  _M_refcount = __refcount;
2265  }
2266  }
2267 
2268  template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
2269  template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
2270  friend class __enable_shared_from_this<_Tp, _Lp>;
2271  friend class enable_shared_from_this<_Tp>;
2272 #ifdef __glibcxx_atomic_shared_ptr
2273  friend _Sp_atomic<weak_ptr<_Tp>>;
2274 #endif
2275 
2276  element_type* _M_ptr; // Contained pointer.
2277  __weak_count<_Lp> _M_refcount; // Reference counter.
2278  };
2279 
2280  // 20.7.2.3.6 weak_ptr specialized algorithms.
2281  template<typename _Tp, _Lock_policy _Lp>
2282  inline void
2283  swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
2284  { __a.swap(__b); }
2285 
2286 #pragma GCC diagnostic push
2287 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2288  template<typename _Tp, typename _Tp1>
2289  struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
2290  {
2291  bool
2292  operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept
2293  { return __lhs.owner_before(__rhs); }
2294 
2295  bool
2296  operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept
2297  { return __lhs.owner_before(__rhs); }
2298 
2299  bool
2300  operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept
2301  { return __lhs.owner_before(__rhs); }
2302  };
2303 #pragma GCC diagnostic pop
2304 
2305  template<>
2306  struct _Sp_owner_less<void, void>
2307  {
2308  template<typename _Tp, typename _Up>
2309  auto
2310  operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept
2311  -> decltype(__lhs.owner_before(__rhs))
2312  { return __lhs.owner_before(__rhs); }
2313 
2314  using is_transparent = void;
2315  };
2316 
2317  template<typename _Tp, _Lock_policy _Lp>
2318  struct owner_less<__shared_ptr<_Tp, _Lp>>
2319  : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
2320  { };
2321 
2322  template<typename _Tp, _Lock_policy _Lp>
2323  struct owner_less<__weak_ptr<_Tp, _Lp>>
2324  : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
2325  { };
2326 
2327 
2328  template<typename _Tp, _Lock_policy _Lp>
2329  class __enable_shared_from_this
2330  {
2331  protected:
2332  constexpr __enable_shared_from_this() noexcept { }
2333 
2334  __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
2335 
2336  __enable_shared_from_this&
2337  operator=(const __enable_shared_from_this&) noexcept
2338  { return *this; }
2339 
2340  ~__enable_shared_from_this() { }
2341 
2342  public:
2343  __shared_ptr<_Tp, _Lp>
2344  shared_from_this()
2345  { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
2346 
2347  __shared_ptr<const _Tp, _Lp>
2348  shared_from_this() const
2349  { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
2350 
2351 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
2352  __weak_ptr<_Tp, _Lp>
2353  weak_from_this() noexcept
2354  { return this->_M_weak_this; }
2355 
2356  __weak_ptr<const _Tp, _Lp>
2357  weak_from_this() const noexcept
2358  { return this->_M_weak_this; }
2359 #endif
2360 
2361  private:
2362  template<typename _Tp1>
2363  void
2364  _M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
2365  { _M_weak_this._M_assign(__p, __n); }
2366 
2367  friend const __enable_shared_from_this*
2368  __enable_shared_from_this_base(const __shared_count<_Lp>&,
2369  const __enable_shared_from_this* __p)
2370  { return __p; }
2371 
2372  template<typename, _Lock_policy>
2373  friend class __shared_ptr;
2374 
2375  mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
2376  };
2377 
2378  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
2379  typename _Alloc, typename... _Args>
2380  inline __shared_ptr<_Tp, _Lp>
2381  __allocate_shared(const _Alloc& __a, _Args&&... __args)
2382  {
2383  static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported");
2384 
2385  return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a},
2386  std::forward<_Args>(__args)...);
2387  }
2388 
2389  template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
2390  typename... _Args>
2391  inline __shared_ptr<_Tp, _Lp>
2392  __make_shared(_Args&&... __args)
2393  {
2394  typedef typename std::remove_const<_Tp>::type _Tp_nc;
2395  return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
2396  std::forward<_Args>(__args)...);
2397  }
2398 
2399  /// std::hash specialization for __shared_ptr.
2400  template<typename _Tp, _Lock_policy _Lp>
2401  struct hash<__shared_ptr<_Tp, _Lp>>
2402  : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
2403  {
2404  size_t
2405  operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
2406  {
2408  __s.get());
2409  }
2410  };
2411 
2412 _GLIBCXX_END_NAMESPACE_VERSION
2413 } // namespace
2414 
2415 #endif // _SHARED_PTR_BASE_H
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:859
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:873
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:826
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:866
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:434
requires requires
Definition: complex:1948
void * align(size_t __align, size_t __size, void *&__ptr, size_t &__space) noexcept
Fit aligned storage in buffer.
Definition: align.h:60
_GLIBCXX26_CONSTEXPR _ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
Default-initializes objects in the range [first,first+count).
constexpr _Tp * to_address(_Tp *__ptr) noexcept
Obtain address referenced by a pointer to an object.
Definition: ptr_traits.h:232
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
Definition: type_traits:119
__bool_constant< false > false_type
The type used as a compile-time boolean with false value.
Definition: type_traits:122
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:52
auto declval() noexcept -> decltype(__declval< _Tp >(0))
Definition: type_traits:2720
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:138
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:72
void lock(_L1 &__l1, _L2 &__l2, _L3 &... __l3)
Generic lock.
Definition: mutex:686
ISO C++ entities toplevel namespace is std.
__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:94
Primary class template hash.
__detected_or_t< value_type *, __pointer, _Alloc > pointer
The allocator's pointer type.
static constexpr pointer allocate(_Alloc &__a, size_type __n)
Allocate memory.
static constexpr void destroy(_Alloc &__a, _Tp *__p) noexcept(_S_nothrow_destroy< _Tp >())
Destroy an object of type _Tp.
requires static constexpr __can_construct< _Alloc, _Tp, _Args... > void construct(_Alloc &__a, _Tp *__p, _Args &&... __args) noexcept(_S_nothrow_construct< _Tp, _Args... >())
Construct an object of type _Tp
_Alloc::value_type value_type
The allocated type.
static constexpr void deallocate(_Alloc &__a, pointer __p, size_type __n)
Deallocate memory.
The standard allocator, as per C++03 [20.4.1].
Definition: allocator.h:134
Base class for all library exceptions.
Definition: exception.h:62
A simple smart pointer providing strict ownership semantics.
Definition: auto_ptr.h:94
Exception possibly thrown by shared_ptr.
virtual char const * what() const noexcept
One of the comparison functors.
Definition: stl_function.h:404
A move-only smart pointer that manages unique ownership of a resource.
Definition: unique_ptr.h:271
Scoped lock idiom.
Definition: concurrence.h:234