libstdc++
bits/shared_ptr.h
Go to the documentation of this file.
1 // shared_ptr and weak_ptr implementation -*- C++ -*-
2 
3 // Copyright (C) 2007-2020 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
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_H
50 #define _SHARED_PTR_H 1
51 
52 #include <bits/shared_ptr_base.h>
53 
54 namespace std _GLIBCXX_VISIBILITY(default)
55 {
56 _GLIBCXX_BEGIN_NAMESPACE_VERSION
57 
58  /**
59  * @addtogroup pointer_abstractions
60  * @{
61  */
62 
63  // 20.7.2.2.11 shared_ptr I/O
64 
65  /// Write the stored pointer to an ostream.
66  /// @relates shared_ptr
67  template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
70  const __shared_ptr<_Tp, _Lp>& __p)
71  {
72  __os << __p.get();
73  return __os;
74  }
75 
76  template<typename _Del, typename _Tp, _Lock_policy _Lp>
77  inline _Del*
78  get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
79  {
80 #if __cpp_rtti
81  return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
82 #else
83  return 0;
84 #endif
85  }
86 
87  /// 20.7.2.2.10 shared_ptr get_deleter
88 
89  /// If `__p` has a deleter of type `_Del`, return a pointer to it.
90  /// @relates shared_ptr
91  template<typename _Del, typename _Tp>
92  inline _Del*
93  get_deleter(const shared_ptr<_Tp>& __p) noexcept
94  {
95 #if __cpp_rtti
96  return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
97 #else
98  return 0;
99 #endif
100  }
101 
102  /**
103  * @brief A smart pointer with reference-counted copy semantics.
104  *
105  * A `shared_ptr` object is either empty or _owns_ a pointer passed
106  * to the constructor. Copies of a `shared_ptr` share ownership of
107  * the same pointer. When the last `shared_ptr` that owns the pointer
108  * is destroyed or reset, the owned pointer is freed (either by `delete`
109  * or by invoking a custom deleter that was passed to the constructor).
110  *
111  * A `shared_ptr` also stores another pointer, which is usually
112  * (but not always) the same pointer as it owns. The stored pointer
113  * can be retrieved by calling the `get()` member function.
114  *
115  * The equality and relational operators for `shared_ptr` only compare
116  * the stored pointer returned by `get()`, not the owned pointer.
117  * To test whether two `shared_ptr` objects share ownership of the same
118  * pointer see `std::shared_ptr::owner_before` and `std::owner_less`.
119  */
120  template<typename _Tp>
121  class shared_ptr : public __shared_ptr<_Tp>
122  {
123  template<typename... _Args>
124  using _Constructible = typename enable_if<
125  is_constructible<__shared_ptr<_Tp>, _Args...>::value
126  >::type;
127 
128  template<typename _Arg>
129  using _Assignable = typename enable_if<
131  >::type;
132 
133  public:
134 
135  /// The type pointed to by the stored pointer, remove_extent_t<_Tp>
136  using element_type = typename __shared_ptr<_Tp>::element_type;
137 
138 #if __cplusplus >= 201703L
139 # define __cpp_lib_shared_ptr_weak_type 201606
140  /// The corresponding weak_ptr type for this shared_ptr
141  using weak_type = weak_ptr<_Tp>;
142 #endif
143  /**
144  * @brief Construct an empty %shared_ptr.
145  * @post use_count()==0 && get()==0
146  */
147  constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
148 
149  shared_ptr(const shared_ptr&) noexcept = default; ///< Copy constructor
150 
151  /**
152  * @brief Construct a %shared_ptr that owns the pointer @a __p.
153  * @param __p A pointer that is convertible to element_type*.
154  * @post use_count() == 1 && get() == __p
155  * @throw std::bad_alloc, in which case @c delete @a __p is called.
156  */
157  template<typename _Yp, typename = _Constructible<_Yp*>>
158  explicit
159  shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }
160 
161  /**
162  * @brief Construct a %shared_ptr that owns the pointer @a __p
163  * and the deleter @a __d.
164  * @param __p A pointer.
165  * @param __d A deleter.
166  * @post use_count() == 1 && get() == __p
167  * @throw std::bad_alloc, in which case @a __d(__p) is called.
168  *
169  * Requirements: _Deleter's copy constructor and destructor must
170  * not throw
171  *
172  * __shared_ptr will release __p by calling __d(__p)
173  */
174  template<typename _Yp, typename _Deleter,
175  typename = _Constructible<_Yp*, _Deleter>>
176  shared_ptr(_Yp* __p, _Deleter __d)
177  : __shared_ptr<_Tp>(__p, std::move(__d)) { }
178 
179  /**
180  * @brief Construct a %shared_ptr that owns a null pointer
181  * and the deleter @a __d.
182  * @param __p A null pointer constant.
183  * @param __d A deleter.
184  * @post use_count() == 1 && get() == __p
185  * @throw std::bad_alloc, in which case @a __d(__p) is called.
186  *
187  * Requirements: _Deleter's copy constructor and destructor must
188  * not throw
189  *
190  * The last owner will call __d(__p)
191  */
192  template<typename _Deleter>
193  shared_ptr(nullptr_t __p, _Deleter __d)
194  : __shared_ptr<_Tp>(__p, std::move(__d)) { }
195 
196  /**
197  * @brief Construct a %shared_ptr that owns the pointer @a __p
198  * and the deleter @a __d.
199  * @param __p A pointer.
200  * @param __d A deleter.
201  * @param __a An allocator.
202  * @post use_count() == 1 && get() == __p
203  * @throw std::bad_alloc, in which case @a __d(__p) is called.
204  *
205  * Requirements: _Deleter's copy constructor and destructor must
206  * not throw _Alloc's copy constructor and destructor must not
207  * throw.
208  *
209  * __shared_ptr will release __p by calling __d(__p)
210  */
211  template<typename _Yp, typename _Deleter, typename _Alloc,
212  typename = _Constructible<_Yp*, _Deleter, _Alloc>>
213  shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
214  : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
215 
216  /**
217  * @brief Construct a %shared_ptr that owns a null pointer
218  * and the deleter @a __d.
219  * @param __p A null pointer constant.
220  * @param __d A deleter.
221  * @param __a An allocator.
222  * @post use_count() == 1 && get() == __p
223  * @throw std::bad_alloc, in which case @a __d(__p) is called.
224  *
225  * Requirements: _Deleter's copy constructor and destructor must
226  * not throw _Alloc's copy constructor and destructor must not
227  * throw.
228  *
229  * The last owner will call __d(__p)
230  */
231  template<typename _Deleter, typename _Alloc>
232  shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
233  : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
234 
235  // Aliasing constructor
236 
237  /**
238  * @brief Constructs a `shared_ptr` instance that stores `__p`
239  * and shares ownership with `__r`.
240  * @param __r A `shared_ptr`.
241  * @param __p A pointer that will remain valid while `*__r` is valid.
242  * @post `get() == __p && use_count() == __r.use_count()`
243  *
244  * This can be used to construct a `shared_ptr` to a sub-object
245  * of an object managed by an existing `shared_ptr`. The complete
246  * object will remain valid while any `shared_ptr` owns it, even
247  * if they don't store a pointer to the complete object.
248  *
249  * @code
250  * shared_ptr<pair<int,int>> pii(new pair<int,int>());
251  * shared_ptr<int> pi(pii, &pii->first);
252  * assert(pii.use_count() == 2);
253  * @endcode
254  */
255  template<typename _Yp>
256  shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
257  : __shared_ptr<_Tp>(__r, __p) { }
258 
259 #if __cplusplus > 201703L
260  // _GLIBCXX_RESOLVE_LIB_DEFECTS
261  // 2996. Missing rvalue overloads for shared_ptr operations
262  /**
263  * @brief Constructs a `shared_ptr` instance that stores `__p`
264  * and shares ownership with `__r`.
265  * @param __r A `shared_ptr`.
266  * @param __p A pointer that will remain valid while `*__r` is valid.
267  * @post `get() == __p && !__r.use_count() && !__r.get()`
268  *
269  * This can be used to construct a `shared_ptr` to a sub-object
270  * of an object managed by an existing `shared_ptr`. The complete
271  * object will remain valid while any `shared_ptr` owns it, even
272  * if they don't store a pointer to the complete object.
273  *
274  * @code
275  * shared_ptr<pair<int,int>> pii(new pair<int,int>());
276  * shared_ptr<int> pi1(pii, &pii->first);
277  * assert(pii.use_count() == 2);
278  * shared_ptr<int> pi2(std::move(pii), &pii->second);
279  * assert(pii.use_count() == 0);
280  * @endcode
281  */
282  template<typename _Yp>
283  shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept
284  : __shared_ptr<_Tp>(std::move(__r), __p) { }
285 #endif
286  /**
287  * @brief If @a __r is empty, constructs an empty %shared_ptr;
288  * otherwise construct a %shared_ptr that shares ownership
289  * with @a __r.
290  * @param __r A %shared_ptr.
291  * @post get() == __r.get() && use_count() == __r.use_count()
292  */
293  template<typename _Yp,
294  typename = _Constructible<const shared_ptr<_Yp>&>>
295  shared_ptr(const shared_ptr<_Yp>& __r) noexcept
296  : __shared_ptr<_Tp>(__r) { }
297 
298  /**
299  * @brief Move-constructs a %shared_ptr instance from @a __r.
300  * @param __r A %shared_ptr rvalue.
301  * @post *this contains the old value of @a __r, @a __r is empty.
302  */
303  shared_ptr(shared_ptr&& __r) noexcept
304  : __shared_ptr<_Tp>(std::move(__r)) { }
305 
306  /**
307  * @brief Move-constructs a %shared_ptr instance from @a __r.
308  * @param __r A %shared_ptr rvalue.
309  * @post *this contains the old value of @a __r, @a __r is empty.
310  */
311  template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
312  shared_ptr(shared_ptr<_Yp>&& __r) noexcept
313  : __shared_ptr<_Tp>(std::move(__r)) { }
314 
315  /**
316  * @brief Constructs a %shared_ptr that shares ownership with @a __r
317  * and stores a copy of the pointer stored in @a __r.
318  * @param __r A weak_ptr.
319  * @post use_count() == __r.use_count()
320  * @throw bad_weak_ptr when __r.expired(),
321  * in which case the constructor has no effect.
322  */
323  template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
324  explicit shared_ptr(const weak_ptr<_Yp>& __r)
325  : __shared_ptr<_Tp>(__r) { }
326 
327 #if _GLIBCXX_USE_DEPRECATED
328 #pragma GCC diagnostic push
329 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
330  template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>
331  shared_ptr(auto_ptr<_Yp>&& __r);
332 #pragma GCC diagnostic pop
333 #endif
334 
335  // _GLIBCXX_RESOLVE_LIB_DEFECTS
336  // 2399. shared_ptr's constructor from unique_ptr should be constrained
337  template<typename _Yp, typename _Del,
338  typename = _Constructible<unique_ptr<_Yp, _Del>>>
340  : __shared_ptr<_Tp>(std::move(__r)) { }
341 
342 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
343  // This non-standard constructor exists to support conversions that
344  // were possible in C++11 and C++14 but are ill-formed in C++17.
345  // If an exception is thrown this constructor has no effect.
346  template<typename _Yp, typename _Del,
347  _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
348  shared_ptr(unique_ptr<_Yp, _Del>&& __r)
349  : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }
350 #endif
351 
352  /**
353  * @brief Construct an empty %shared_ptr.
354  * @post use_count() == 0 && get() == nullptr
355  */
356  constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
357 
358  shared_ptr& operator=(const shared_ptr&) noexcept = default;
359 
360  template<typename _Yp>
361  _Assignable<const shared_ptr<_Yp>&>
362  operator=(const shared_ptr<_Yp>& __r) noexcept
363  {
364  this->__shared_ptr<_Tp>::operator=(__r);
365  return *this;
366  }
367 
368 #if _GLIBCXX_USE_DEPRECATED
369 #pragma GCC diagnostic push
370 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
371  template<typename _Yp>
372  _Assignable<auto_ptr<_Yp>>
373  operator=(auto_ptr<_Yp>&& __r)
374  {
375  this->__shared_ptr<_Tp>::operator=(std::move(__r));
376  return *this;
377  }
378 #pragma GCC diagnostic pop
379 #endif
380 
381  shared_ptr&
382  operator=(shared_ptr&& __r) noexcept
383  {
384  this->__shared_ptr<_Tp>::operator=(std::move(__r));
385  return *this;
386  }
387 
388  template<class _Yp>
389  _Assignable<shared_ptr<_Yp>>
390  operator=(shared_ptr<_Yp>&& __r) noexcept
391  {
392  this->__shared_ptr<_Tp>::operator=(std::move(__r));
393  return *this;
394  }
395 
396  template<typename _Yp, typename _Del>
397  _Assignable<unique_ptr<_Yp, _Del>>
398  operator=(unique_ptr<_Yp, _Del>&& __r)
399  {
400  this->__shared_ptr<_Tp>::operator=(std::move(__r));
401  return *this;
402  }
403 
404  private:
405  // This constructor is non-standard, it is used by allocate_shared.
406  template<typename _Alloc, typename... _Args>
407  shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
408  : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
409  { }
410 
411  template<typename _Yp, typename _Alloc, typename... _Args>
412  friend shared_ptr<_Yp>
413  allocate_shared(const _Alloc& __a, _Args&&... __args);
414 
415  // This constructor is non-standard, it is used by weak_ptr::lock().
416  shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
417  : __shared_ptr<_Tp>(__r, std::nothrow) { }
418 
419  friend class weak_ptr<_Tp>;
420  };
421 
422 #if __cpp_deduction_guides >= 201606
423  template<typename _Tp>
424  shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
425  template<typename _Tp, typename _Del>
426  shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>;
427 #endif
428 
429  // 20.7.2.2.7 shared_ptr comparisons
430 
431  /// @relates shared_ptr @{
432 
433  /// Equality operator for shared_ptr objects, compares the stored pointers
434  template<typename _Tp, typename _Up>
435  _GLIBCXX_NODISCARD inline bool
436  operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
437  { return __a.get() == __b.get(); }
438 
439  /// shared_ptr comparison with nullptr
440  template<typename _Tp>
441  _GLIBCXX_NODISCARD inline bool
442  operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
443  { return !__a; }
444 
445 #ifdef __cpp_lib_three_way_comparison
446  template<typename _Tp, typename _Up>
447  inline strong_ordering
448  operator<=>(const shared_ptr<_Tp>& __a,
449  const shared_ptr<_Up>& __b) noexcept
450  { return compare_three_way()(__a.get(), __b.get()); }
451 
452  template<typename _Tp>
453  inline strong_ordering
454  operator<=>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
455  {
456  using pointer = typename shared_ptr<_Tp>::element_type*;
457  return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
458  }
459 #else
460  /// shared_ptr comparison with nullptr
461  template<typename _Tp>
462  _GLIBCXX_NODISCARD inline bool
463  operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
464  { return !__a; }
465 
466  /// Inequality operator for shared_ptr objects, compares the stored pointers
467  template<typename _Tp, typename _Up>
468  _GLIBCXX_NODISCARD inline bool
469  operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
470  { return __a.get() != __b.get(); }
471 
472  /// shared_ptr comparison with nullptr
473  template<typename _Tp>
474  _GLIBCXX_NODISCARD inline bool
475  operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
476  { return (bool)__a; }
477 
478  /// shared_ptr comparison with nullptr
479  template<typename _Tp>
480  _GLIBCXX_NODISCARD inline bool
481  operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
482  { return (bool)__a; }
483 
484  /// Relational operator for shared_ptr objects, compares the stored pointers
485  template<typename _Tp, typename _Up>
486  _GLIBCXX_NODISCARD inline bool
487  operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
488  {
489  using _Tp_elt = typename shared_ptr<_Tp>::element_type;
490  using _Up_elt = typename shared_ptr<_Up>::element_type;
491  using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
492  return less<_Vp>()(__a.get(), __b.get());
493  }
494 
495  /// shared_ptr comparison with nullptr
496  template<typename _Tp>
497  _GLIBCXX_NODISCARD inline bool
498  operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
499  {
500  using _Tp_elt = typename shared_ptr<_Tp>::element_type;
501  return less<_Tp_elt*>()(__a.get(), nullptr);
502  }
503 
504  /// shared_ptr comparison with nullptr
505  template<typename _Tp>
506  _GLIBCXX_NODISCARD inline bool
507  operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
508  {
509  using _Tp_elt = typename shared_ptr<_Tp>::element_type;
510  return less<_Tp_elt*>()(nullptr, __a.get());
511  }
512 
513  /// Relational operator for shared_ptr objects, compares the stored pointers
514  template<typename _Tp, typename _Up>
515  _GLIBCXX_NODISCARD inline bool
516  operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
517  { return !(__b < __a); }
518 
519  /// shared_ptr comparison with nullptr
520  template<typename _Tp>
521  _GLIBCXX_NODISCARD inline bool
522  operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
523  { return !(nullptr < __a); }
524 
525  /// shared_ptr comparison with nullptr
526  template<typename _Tp>
527  _GLIBCXX_NODISCARD inline bool
528  operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
529  { return !(__a < nullptr); }
530 
531  /// Relational operator for shared_ptr objects, compares the stored pointers
532  template<typename _Tp, typename _Up>
533  _GLIBCXX_NODISCARD inline bool
534  operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
535  { return (__b < __a); }
536 
537  /// shared_ptr comparison with nullptr
538  template<typename _Tp>
539  _GLIBCXX_NODISCARD inline bool
540  operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
541  { return nullptr < __a; }
542 
543  /// shared_ptr comparison with nullptr
544  template<typename _Tp>
545  _GLIBCXX_NODISCARD inline bool
546  operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
547  { return __a < nullptr; }
548 
549  /// Relational operator for shared_ptr objects, compares the stored pointers
550  template<typename _Tp, typename _Up>
551  _GLIBCXX_NODISCARD inline bool
552  operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
553  { return !(__a < __b); }
554 
555  /// shared_ptr comparison with nullptr
556  template<typename _Tp>
557  _GLIBCXX_NODISCARD inline bool
558  operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
559  { return !(__a < nullptr); }
560 
561  /// shared_ptr comparison with nullptr
562  template<typename _Tp>
563  _GLIBCXX_NODISCARD inline bool
564  operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
565  { return !(nullptr < __a); }
566 #endif
567 
568  // 20.7.2.2.8 shared_ptr specialized algorithms.
569 
570  /// Swap overload for shared_ptr
571  template<typename _Tp>
572  inline void
573  swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
574  { __a.swap(__b); }
575 
576  // 20.7.2.2.9 shared_ptr casts.
577 
578  /// Convert type of `shared_ptr`, via `static_cast`
579  template<typename _Tp, typename _Up>
580  inline shared_ptr<_Tp>
582  {
583  using _Sp = shared_ptr<_Tp>;
584  return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
585  }
586 
587  /// Convert type of `shared_ptr`, via `const_cast`
588  template<typename _Tp, typename _Up>
589  inline shared_ptr<_Tp>
590  const_pointer_cast(const shared_ptr<_Up>& __r) noexcept
591  {
592  using _Sp = shared_ptr<_Tp>;
593  return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
594  }
595 
596  /// Convert type of `shared_ptr`, via `dynamic_cast`
597  template<typename _Tp, typename _Up>
598  inline shared_ptr<_Tp>
600  {
601  using _Sp = shared_ptr<_Tp>;
602  if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
603  return _Sp(__r, __p);
604  return _Sp();
605  }
606 
607 #if __cplusplus >= 201703L
608  /// Convert type of `shared_ptr`, via `reinterpret_cast`
609  template<typename _Tp, typename _Up>
610  inline shared_ptr<_Tp>
611  reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
612  {
613  using _Sp = shared_ptr<_Tp>;
614  return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
615  }
616 
617 #if __cplusplus > 201703L
618  // _GLIBCXX_RESOLVE_LIB_DEFECTS
619  // 2996. Missing rvalue overloads for shared_ptr operations
620 
621  /// Convert type of `shared_ptr` rvalue, via `static_cast`
622  template<typename _Tp, typename _Up>
623  inline shared_ptr<_Tp>
624  static_pointer_cast(shared_ptr<_Up>&& __r) noexcept
625  {
626  using _Sp = shared_ptr<_Tp>;
627  return _Sp(std::move(__r),
628  static_cast<typename _Sp::element_type*>(__r.get()));
629  }
630 
631  /// Convert type of `shared_ptr` rvalue, via `const_cast`
632  template<typename _Tp, typename _Up>
633  inline shared_ptr<_Tp>
634  const_pointer_cast(shared_ptr<_Up>&& __r) noexcept
635  {
636  using _Sp = shared_ptr<_Tp>;
637  return _Sp(std::move(__r),
638  const_cast<typename _Sp::element_type*>(__r.get()));
639  }
640 
641  /// Convert type of `shared_ptr` rvalue, via `dynamic_cast`
642  template<typename _Tp, typename _Up>
643  inline shared_ptr<_Tp>
644  dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept
645  {
646  using _Sp = shared_ptr<_Tp>;
647  if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
648  return _Sp(std::move(__r), __p);
649  return _Sp();
650  }
651 
652  /// Convert type of `shared_ptr` rvalue, via `reinterpret_cast`
653  template<typename _Tp, typename _Up>
654  inline shared_ptr<_Tp>
655  reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept
656  {
657  using _Sp = shared_ptr<_Tp>;
658  return _Sp(std::move(__r),
659  reinterpret_cast<typename _Sp::element_type*>(__r.get()));
660  }
661 #endif // C++20
662 #endif // C++17
663 
664  /// @}
665 
666  /**
667  * @brief A non-owning observer for a pointer owned by a shared_ptr
668  *
669  * A weak_ptr provides a safe alternative to a raw pointer when you want
670  * a non-owning reference to an object that is managed by a shared_ptr.
671  *
672  * Unlike a raw pointer, a weak_ptr can be converted to a new shared_ptr
673  * that shares ownership with every other shared_ptr that already owns
674  * the pointer. In other words you can upgrade from a non-owning "weak"
675  * reference to an owning shared_ptr, without having access to any of
676  * the existing shared_ptr objects.
677  *
678  * Also unlike a raw pointer, a weak_ptr does not become "dangling" after
679  * the object it points to has been destroyed. Instead, a weak_ptr
680  * becomes _expired_ and can no longer be converted to a shared_ptr that
681  * owns the freed pointer, so you cannot accidentally access the pointed-to
682  * object after it has been destroyed.
683  */
684  template<typename _Tp>
685  class weak_ptr : public __weak_ptr<_Tp>
686  {
687  template<typename _Arg>
688  using _Constructible = typename enable_if<
690  >::type;
691 
692  template<typename _Arg>
693  using _Assignable = typename enable_if<
694  is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&
695  >::type;
696 
697  public:
698  constexpr weak_ptr() noexcept = default;
699 
700  template<typename _Yp,
701  typename = _Constructible<const shared_ptr<_Yp>&>>
702  weak_ptr(const shared_ptr<_Yp>& __r) noexcept
703  : __weak_ptr<_Tp>(__r) { }
704 
705  weak_ptr(const weak_ptr&) noexcept = default;
706 
707  template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
708  weak_ptr(const weak_ptr<_Yp>& __r) noexcept
709  : __weak_ptr<_Tp>(__r) { }
710 
711  weak_ptr(weak_ptr&&) noexcept = default;
712 
713  template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>
714  weak_ptr(weak_ptr<_Yp>&& __r) noexcept
715  : __weak_ptr<_Tp>(std::move(__r)) { }
716 
717  weak_ptr&
718  operator=(const weak_ptr& __r) noexcept = default;
719 
720  template<typename _Yp>
721  _Assignable<const weak_ptr<_Yp>&>
722  operator=(const weak_ptr<_Yp>& __r) noexcept
723  {
724  this->__weak_ptr<_Tp>::operator=(__r);
725  return *this;
726  }
727 
728  template<typename _Yp>
729  _Assignable<const shared_ptr<_Yp>&>
730  operator=(const shared_ptr<_Yp>& __r) noexcept
731  {
732  this->__weak_ptr<_Tp>::operator=(__r);
733  return *this;
734  }
735 
736  weak_ptr&
737  operator=(weak_ptr&& __r) noexcept = default;
738 
739  template<typename _Yp>
740  _Assignable<weak_ptr<_Yp>>
741  operator=(weak_ptr<_Yp>&& __r) noexcept
742  {
743  this->__weak_ptr<_Tp>::operator=(std::move(__r));
744  return *this;
745  }
746 
748  lock() const noexcept
749  { return shared_ptr<_Tp>(*this, std::nothrow); }
750  };
751 
752 #if __cpp_deduction_guides >= 201606
753  template<typename _Tp>
755 #endif
756 
757  // 20.7.2.3.6 weak_ptr specialized algorithms.
758  /// Swap overload for weak_ptr
759  /// @relates weak_ptr
760  template<typename _Tp>
761  inline void
762  swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
763  { __a.swap(__b); }
764 
765 
766  /// Primary template owner_less
767  template<typename _Tp = void>
768  struct owner_less;
769 
770  /// Void specialization of owner_less compares either shared_ptr or weak_ptr
771  template<>
772  struct owner_less<void> : _Sp_owner_less<void, void>
773  { };
774 
775  /// Partial specialization of owner_less for shared_ptr.
776  template<typename _Tp>
777  struct owner_less<shared_ptr<_Tp>>
778  : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
779  { };
780 
781  /// Partial specialization of owner_less for weak_ptr.
782  template<typename _Tp>
783  struct owner_less<weak_ptr<_Tp>>
784  : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
785  { };
786 
787  /**
788  * @brief Base class allowing use of member function shared_from_this.
789  */
790  template<typename _Tp>
792  {
793  protected:
794  constexpr enable_shared_from_this() noexcept { }
795 
797 
799  operator=(const enable_shared_from_this&) noexcept
800  { return *this; }
801 
803 
804  public:
806  shared_from_this()
807  { return shared_ptr<_Tp>(this->_M_weak_this); }
808 
810  shared_from_this() const
811  { return shared_ptr<const _Tp>(this->_M_weak_this); }
812 
813 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
814 #define __cpp_lib_enable_shared_from_this 201603
816  weak_from_this() noexcept
817  { return this->_M_weak_this; }
818 
820  weak_from_this() const noexcept
821  { return this->_M_weak_this; }
822 #endif
823 
824  private:
825  template<typename _Tp1>
826  void
827  _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
828  { _M_weak_this._M_assign(__p, __n); }
829 
830  // Found by ADL when this is an associated class.
831  friend const enable_shared_from_this*
832  __enable_shared_from_this_base(const __shared_count<>&,
833  const enable_shared_from_this* __p)
834  { return __p; }
835 
836  template<typename, _Lock_policy>
837  friend class __shared_ptr;
838 
839  mutable weak_ptr<_Tp> _M_weak_this;
840  };
841 
842  /// @relates shared_ptr @{
843 
844  /**
845  * @brief Create an object that is owned by a shared_ptr.
846  * @param __a An allocator.
847  * @param __args Arguments for the @a _Tp object's constructor.
848  * @return A shared_ptr that owns the newly created object.
849  * @throw An exception thrown from @a _Alloc::allocate or from the
850  * constructor of @a _Tp.
851  *
852  * A copy of @a __a will be used to allocate memory for the shared_ptr
853  * and the new object.
854  */
855  template<typename _Tp, typename _Alloc, typename... _Args>
856  inline shared_ptr<_Tp>
857  allocate_shared(const _Alloc& __a, _Args&&... __args)
858  {
859  static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported");
860 
861  return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
862  std::forward<_Args>(__args)...);
863  }
864 
865  /**
866  * @brief Create an object that is owned by a shared_ptr.
867  * @param __args Arguments for the @a _Tp object's constructor.
868  * @return A shared_ptr that owns the newly created object.
869  * @throw std::bad_alloc, or an exception thrown from the
870  * constructor of @a _Tp.
871  */
872  template<typename _Tp, typename... _Args>
873  inline shared_ptr<_Tp>
874  make_shared(_Args&&... __args)
875  {
876  typedef typename std::remove_cv<_Tp>::type _Tp_nc;
877  return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
878  std::forward<_Args>(__args)...);
879  }
880 
881  /// std::hash specialization for shared_ptr.
882  template<typename _Tp>
883  struct hash<shared_ptr<_Tp>>
884  : public __hash_base<size_t, shared_ptr<_Tp>>
885  {
886  size_t
887  operator()(const shared_ptr<_Tp>& __s) const noexcept
888  {
890  }
891  };
892 
893  /// @} relates shared_ptr
894  /// @} group pointer_abstractions
895 
896 #if __cplusplus >= 201703L
897  namespace __detail::__variant
898  {
899  template<typename> struct _Never_valueless_alt; // see <variant>
900 
901  // Provide the strong exception-safety guarantee when emplacing a
902  // shared_ptr into a variant.
903  template<typename _Tp>
904  struct _Never_valueless_alt<std::shared_ptr<_Tp>>
906  { };
907 
908  // Provide the strong exception-safety guarantee when emplacing a
909  // weak_ptr into a variant.
910  template<typename _Tp>
911  struct _Never_valueless_alt<std::weak_ptr<_Tp>>
913  { };
914  } // namespace __detail::__variant
915 #endif // C++17
916 
917 _GLIBCXX_END_NAMESPACE_VERSION
918 } // namespace
919 
920 #endif // _SHARED_PTR_H
shared_ptr< _Tp > make_shared(_Args &&... __args)
Create an object that is owned by a shared_ptr.
bool operator!=(nullptr_t, const shared_ptr< _Tp > &__a) noexcept
shared_ptr comparison with nullptr
bool operator>(const shared_ptr< _Tp > &__a, nullptr_t) noexcept
shared_ptr comparison with nullptr
bool operator==(const shared_ptr< _Tp > &__a, nullptr_t) noexcept
shared_ptr comparison with nullptr
bool operator==(nullptr_t, const shared_ptr< _Tp > &__a) noexcept
shared_ptr comparison with nullptr
shared_ptr< _Tp > static_pointer_cast(const shared_ptr< _Up > &__r) noexcept
Convert type of shared_ptr, via static_cast
bool operator!=(const shared_ptr< _Tp > &__a, const shared_ptr< _Up > &__b) noexcept
Inequality operator for shared_ptr objects, compares the stored pointers.
_Del * get_deleter(const shared_ptr< _Tp > &__p) noexcept
20.7.2.2.10 shared_ptr get_deleter
bool operator==(const shared_ptr< _Tp > &__a, const shared_ptr< _Up > &__b) noexcept
bool operator>=(const shared_ptr< _Tp > &__a, nullptr_t) noexcept
shared_ptr comparison with nullptr
void swap(weak_ptr< _Tp > &__a, weak_ptr< _Tp > &__b) noexcept
Swap overload for weak_ptr.
shared_ptr< _Tp > allocate_shared(const _Alloc &__a, _Args &&... __args)
Create an object that is owned by a shared_ptr.
bool operator>(nullptr_t, const shared_ptr< _Tp > &__a) noexcept
shared_ptr comparison with nullptr
bool operator>=(nullptr_t, const shared_ptr< _Tp > &__a) noexcept
shared_ptr comparison with nullptr
shared_ptr< _Tp > dynamic_pointer_cast(const shared_ptr< _Up > &__r) noexcept
Convert type of shared_ptr, via dynamic_cast
shared_ptr< _Tp > const_pointer_cast(const shared_ptr< _Up > &__r) noexcept
Convert type of shared_ptr, via const_cast
bool operator>(const shared_ptr< _Tp > &__a, const shared_ptr< _Up > &__b) noexcept
Relational operator for shared_ptr objects, compares the stored pointers.
bool operator>=(const shared_ptr< _Tp > &__a, const shared_ptr< _Up > &__b) noexcept
Relational operator for shared_ptr objects, compares the stored pointers.
bool operator!=(const shared_ptr< _Tp > &__a, nullptr_t) noexcept
shared_ptr comparison with nullptr
void swap(shared_ptr< _Tp > &__a, shared_ptr< _Tp > &__b) noexcept
Swap overload for shared_ptr.
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
ISO C++ entities toplevel namespace is std.
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition: bitset:1540
__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
Template class basic_ostream.
Definition: ostream:59
Primary class template hash.
integral_constant
Definition: type_traits:58
is_array
Definition: type_traits:400
is_constructible
Definition: type_traits:908
is_assignable
Definition: type_traits:1071
Define a member typedef type only if a boolean constant is true.
Definition: type_traits:2183
common_type
Definition: type_traits:2215
The standard allocator, as per C++03 [20.4.1].
Definition: allocator.h:123
A smart pointer with reference-counted copy semantics.
typename __shared_ptr< _Tp >::element_type element_type
The type pointed to by the stored pointer, remove_extent_t<_Tp>
shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
Construct a shared_ptr that owns a null pointer and the deleter __d.
shared_ptr(const shared_ptr< _Yp > &__r) noexcept
If __r is empty, constructs an empty shared_ptr; otherwise construct a shared_ptr that shares ownersh...
shared_ptr(shared_ptr< _Yp > &&__r) noexcept
Move-constructs a shared_ptr instance from __r.
shared_ptr(_Yp *__p, _Deleter __d, _Alloc __a)
Construct a shared_ptr that owns the pointer __p and the deleter __d.
constexpr shared_ptr() noexcept
Construct an empty shared_ptr.
shared_ptr(const shared_ptr &) noexcept=default
Copy constructor.
shared_ptr(shared_ptr &&__r) noexcept
Move-constructs a shared_ptr instance from __r.
shared_ptr(_Yp *__p)
Construct a shared_ptr that owns the pointer __p.
shared_ptr(nullptr_t __p, _Deleter __d)
Construct a shared_ptr that owns a null pointer and the deleter __d.
shared_ptr(_Yp *__p, _Deleter __d)
Construct a shared_ptr that owns the pointer __p and the deleter __d.
shared_ptr(const shared_ptr< _Yp > &__r, element_type *__p) noexcept
Constructs a shared_ptr instance that stores __p and shares ownership with __r.
shared_ptr(const weak_ptr< _Yp > &__r)
Constructs a shared_ptr that shares ownership with __r and stores a copy of the pointer stored in __r...
constexpr shared_ptr(nullptr_t) noexcept
Construct an empty shared_ptr.
A non-owning observer for a pointer owned by a shared_ptr.
Primary template owner_less.
Base class allowing use of member function shared_from_this.
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