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>
69  operator<<(std::basic_ostream<_Ch, _Tr>& __os,
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  /// shared_ptr comparison with nullptr
446  template<typename _Tp>
447  _GLIBCXX_NODISCARD inline bool
448  operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
449  { return !__a; }
450 
451  /// Inequality operator for shared_ptr objects, compares the stored pointers
452  template<typename _Tp, typename _Up>
453  _GLIBCXX_NODISCARD inline bool
454  operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
455  { return __a.get() != __b.get(); }
456 
457  /// shared_ptr comparison with nullptr
458  template<typename _Tp>
459  _GLIBCXX_NODISCARD inline bool
460  operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
461  { return (bool)__a; }
462 
463  /// shared_ptr comparison with nullptr
464  template<typename _Tp>
465  _GLIBCXX_NODISCARD inline bool
466  operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
467  { return (bool)__a; }
468 
469  /// Relational operator for shared_ptr objects, compares the stored pointers
470  template<typename _Tp, typename _Up>
471  _GLIBCXX_NODISCARD inline bool
472  operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
473  {
474  using _Tp_elt = typename shared_ptr<_Tp>::element_type;
475  using _Up_elt = typename shared_ptr<_Up>::element_type;
476  using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
477  return less<_Vp>()(__a.get(), __b.get());
478  }
479 
480  /// shared_ptr comparison with nullptr
481  template<typename _Tp>
482  _GLIBCXX_NODISCARD inline bool
483  operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
484  {
485  using _Tp_elt = typename shared_ptr<_Tp>::element_type;
486  return less<_Tp_elt*>()(__a.get(), nullptr);
487  }
488 
489  /// shared_ptr comparison with nullptr
490  template<typename _Tp>
491  _GLIBCXX_NODISCARD inline bool
492  operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
493  {
494  using _Tp_elt = typename shared_ptr<_Tp>::element_type;
495  return less<_Tp_elt*>()(nullptr, __a.get());
496  }
497 
498  /// Relational operator for shared_ptr objects, compares the stored pointers
499  template<typename _Tp, typename _Up>
500  _GLIBCXX_NODISCARD inline bool
501  operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
502  { return !(__b < __a); }
503 
504  /// shared_ptr comparison with nullptr
505  template<typename _Tp>
506  _GLIBCXX_NODISCARD inline bool
507  operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
508  { return !(nullptr < __a); }
509 
510  /// shared_ptr comparison with nullptr
511  template<typename _Tp>
512  _GLIBCXX_NODISCARD inline bool
513  operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
514  { return !(__a < nullptr); }
515 
516  /// Relational operator for shared_ptr objects, compares the stored pointers
517  template<typename _Tp, typename _Up>
518  _GLIBCXX_NODISCARD inline bool
519  operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
520  { return (__b < __a); }
521 
522  /// shared_ptr comparison with nullptr
523  template<typename _Tp>
524  _GLIBCXX_NODISCARD inline bool
525  operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
526  { return nullptr < __a; }
527 
528  /// shared_ptr comparison with nullptr
529  template<typename _Tp>
530  _GLIBCXX_NODISCARD inline bool
531  operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
532  { return __a < nullptr; }
533 
534  /// Relational operator for shared_ptr objects, compares the stored pointers
535  template<typename _Tp, typename _Up>
536  _GLIBCXX_NODISCARD inline bool
537  operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
538  { return !(__a < __b); }
539 
540  /// shared_ptr comparison with nullptr
541  template<typename _Tp>
542  _GLIBCXX_NODISCARD inline bool
543  operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
544  { return !(__a < nullptr); }
545 
546  /// shared_ptr comparison with nullptr
547  template<typename _Tp>
548  _GLIBCXX_NODISCARD inline bool
549  operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
550  { return !(nullptr < __a); }
551 
552  // 20.7.2.2.8 shared_ptr specialized algorithms.
553 
554  /// Swap overload for shared_ptr
555  template<typename _Tp>
556  inline void
557  swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
558  { __a.swap(__b); }
559 
560  // 20.7.2.2.9 shared_ptr casts.
561 
562  /// Convert type of `shared_ptr`, via `static_cast`
563  template<typename _Tp, typename _Up>
564  inline shared_ptr<_Tp>
566  {
567  using _Sp = shared_ptr<_Tp>;
568  return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
569  }
570 
571  /// Convert type of `shared_ptr`, via `const_cast`
572  template<typename _Tp, typename _Up>
573  inline shared_ptr<_Tp>
574  const_pointer_cast(const shared_ptr<_Up>& __r) noexcept
575  {
576  using _Sp = shared_ptr<_Tp>;
577  return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
578  }
579 
580  /// Convert type of `shared_ptr`, via `dynamic_cast`
581  template<typename _Tp, typename _Up>
582  inline shared_ptr<_Tp>
584  {
585  using _Sp = shared_ptr<_Tp>;
586  if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
587  return _Sp(__r, __p);
588  return _Sp();
589  }
590 
591 #if __cplusplus >= 201703L
592  /// Convert type of `shared_ptr`, via `reinterpret_cast`
593  template<typename _Tp, typename _Up>
594  inline shared_ptr<_Tp>
595  reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
596  {
597  using _Sp = shared_ptr<_Tp>;
598  return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
599  }
600 
601 #if __cplusplus > 201703L
602  // _GLIBCXX_RESOLVE_LIB_DEFECTS
603  // 2996. Missing rvalue overloads for shared_ptr operations
604 
605  /// Convert type of `shared_ptr` rvalue, via `static_cast`
606  template<typename _Tp, typename _Up>
607  inline shared_ptr<_Tp>
608  static_pointer_cast(shared_ptr<_Up>&& __r) noexcept
609  {
610  using _Sp = shared_ptr<_Tp>;
611  return _Sp(std::move(__r),
612  static_cast<typename _Sp::element_type*>(__r.get()));
613  }
614 
615  /// Convert type of `shared_ptr` rvalue, via `const_cast`
616  template<typename _Tp, typename _Up>
617  inline shared_ptr<_Tp>
618  const_pointer_cast(shared_ptr<_Up>&& __r) noexcept
619  {
620  using _Sp = shared_ptr<_Tp>;
621  return _Sp(std::move(__r),
622  const_cast<typename _Sp::element_type*>(__r.get()));
623  }
624 
625  /// Convert type of `shared_ptr` rvalue, via `dynamic_cast`
626  template<typename _Tp, typename _Up>
627  inline shared_ptr<_Tp>
628  dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept
629  {
630  using _Sp = shared_ptr<_Tp>;
631  if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
632  return _Sp(std::move(__r), __p);
633  return _Sp();
634  }
635 
636  /// Convert type of `shared_ptr` rvalue, via `reinterpret_cast`
637  template<typename _Tp, typename _Up>
638  inline shared_ptr<_Tp>
639  reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept
640  {
641  using _Sp = shared_ptr<_Tp>;
642  return _Sp(std::move(__r),
643  reinterpret_cast<typename _Sp::element_type*>(__r.get()));
644  }
645 #endif // C++20
646 #endif // C++17
647 
648  // @}
649 
650  /**
651  * @brief A non-owning observer for a pointer owned by a shared_ptr
652  *
653  * A weak_ptr provides a safe alternative to a raw pointer when you want
654  * a non-owning reference to an object that is managed by a shared_ptr.
655  *
656  * Unlike a raw pointer, a weak_ptr can be converted to a new shared_ptr
657  * that shares ownership with every other shared_ptr that already owns
658  * the pointer. In other words you can upgrade from a non-owning "weak"
659  * reference to an owning shared_ptr, without having access to any of
660  * the existing shared_ptr objects.
661  *
662  * Also unlike a raw pointer, a weak_ptr does not become "dangling" after
663  * the object it points to has been destroyed. Instead, a weak_ptr
664  * becomes _expired_ and can no longer be converted to a shared_ptr that
665  * owns the freed pointer, so you cannot accidentally access the pointed-to
666  * object after it has been destroyed.
667  */
668  template<typename _Tp>
669  class weak_ptr : public __weak_ptr<_Tp>
670  {
671  template<typename _Arg>
672  using _Constructible = typename enable_if<
674  >::type;
675 
676  template<typename _Arg>
677  using _Assignable = typename enable_if<
678  is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&
679  >::type;
680 
681  public:
682  constexpr weak_ptr() noexcept = default;
683 
684  template<typename _Yp,
685  typename = _Constructible<const shared_ptr<_Yp>&>>
686  weak_ptr(const shared_ptr<_Yp>& __r) noexcept
687  : __weak_ptr<_Tp>(__r) { }
688 
689  weak_ptr(const weak_ptr&) noexcept = default;
690 
691  template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
692  weak_ptr(const weak_ptr<_Yp>& __r) noexcept
693  : __weak_ptr<_Tp>(__r) { }
694 
695  weak_ptr(weak_ptr&&) noexcept = default;
696 
697  template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>
698  weak_ptr(weak_ptr<_Yp>&& __r) noexcept
699  : __weak_ptr<_Tp>(std::move(__r)) { }
700 
701  weak_ptr&
702  operator=(const weak_ptr& __r) noexcept = default;
703 
704  template<typename _Yp>
705  _Assignable<const weak_ptr<_Yp>&>
706  operator=(const weak_ptr<_Yp>& __r) noexcept
707  {
708  this->__weak_ptr<_Tp>::operator=(__r);
709  return *this;
710  }
711 
712  template<typename _Yp>
713  _Assignable<const shared_ptr<_Yp>&>
714  operator=(const shared_ptr<_Yp>& __r) noexcept
715  {
716  this->__weak_ptr<_Tp>::operator=(__r);
717  return *this;
718  }
719 
720  weak_ptr&
721  operator=(weak_ptr&& __r) noexcept = default;
722 
723  template<typename _Yp>
724  _Assignable<weak_ptr<_Yp>>
725  operator=(weak_ptr<_Yp>&& __r) noexcept
726  {
727  this->__weak_ptr<_Tp>::operator=(std::move(__r));
728  return *this;
729  }
730 
732  lock() const noexcept
733  { return shared_ptr<_Tp>(*this, std::nothrow); }
734  };
735 
736 #if __cpp_deduction_guides >= 201606
737  template<typename _Tp>
739 #endif
740 
741  // 20.7.2.3.6 weak_ptr specialized algorithms.
742  /// Swap overload for weak_ptr
743  /// @relates weak_ptr
744  template<typename _Tp>
745  inline void
746  swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
747  { __a.swap(__b); }
748 
749 
750  /// Primary template owner_less
751  template<typename _Tp = void>
752  struct owner_less;
753 
754  /// Void specialization of owner_less compares either shared_ptr or weak_ptr
755  template<>
756  struct owner_less<void> : _Sp_owner_less<void, void>
757  { };
758 
759  /// Partial specialization of owner_less for shared_ptr.
760  template<typename _Tp>
761  struct owner_less<shared_ptr<_Tp>>
762  : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
763  { };
764 
765  /// Partial specialization of owner_less for weak_ptr.
766  template<typename _Tp>
767  struct owner_less<weak_ptr<_Tp>>
768  : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
769  { };
770 
771  /**
772  * @brief Base class allowing use of member function shared_from_this.
773  */
774  template<typename _Tp>
776  {
777  protected:
778  constexpr enable_shared_from_this() noexcept { }
779 
781 
783  operator=(const enable_shared_from_this&) noexcept
784  { return *this; }
785 
787 
788  public:
790  shared_from_this()
791  { return shared_ptr<_Tp>(this->_M_weak_this); }
792 
794  shared_from_this() const
795  { return shared_ptr<const _Tp>(this->_M_weak_this); }
796 
797 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
798 #define __cpp_lib_enable_shared_from_this 201603
800  weak_from_this() noexcept
801  { return this->_M_weak_this; }
802 
804  weak_from_this() const noexcept
805  { return this->_M_weak_this; }
806 #endif
807 
808  private:
809  template<typename _Tp1>
810  void
811  _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
812  { _M_weak_this._M_assign(__p, __n); }
813 
814  // Found by ADL when this is an associated class.
815  friend const enable_shared_from_this*
816  __enable_shared_from_this_base(const __shared_count<>&,
817  const enable_shared_from_this* __p)
818  { return __p; }
819 
820  template<typename, _Lock_policy>
821  friend class __shared_ptr;
822 
823  mutable weak_ptr<_Tp> _M_weak_this;
824  };
825 
826  /// @relates shared_ptr @{
827 
828  /**
829  * @brief Create an object that is owned by a shared_ptr.
830  * @param __a An allocator.
831  * @param __args Arguments for the @a _Tp object's constructor.
832  * @return A shared_ptr that owns the newly created object.
833  * @throw An exception thrown from @a _Alloc::allocate or from the
834  * constructor of @a _Tp.
835  *
836  * A copy of @a __a will be used to allocate memory for the shared_ptr
837  * and the new object.
838  */
839  template<typename _Tp, typename _Alloc, typename... _Args>
840  inline shared_ptr<_Tp>
841  allocate_shared(const _Alloc& __a, _Args&&... __args)
842  {
843  return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
844  std::forward<_Args>(__args)...);
845  }
846 
847  /**
848  * @brief Create an object that is owned by a shared_ptr.
849  * @param __args Arguments for the @a _Tp object's constructor.
850  * @return A shared_ptr that owns the newly created object.
851  * @throw std::bad_alloc, or an exception thrown from the
852  * constructor of @a _Tp.
853  */
854  template<typename _Tp, typename... _Args>
855  inline shared_ptr<_Tp>
856  make_shared(_Args&&... __args)
857  {
858  typedef typename std::remove_cv<_Tp>::type _Tp_nc;
859  return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
860  std::forward<_Args>(__args)...);
861  }
862 
863  /// std::hash specialization for shared_ptr.
864  template<typename _Tp>
865  struct hash<shared_ptr<_Tp>>
866  : public __hash_base<size_t, shared_ptr<_Tp>>
867  {
868  size_t
869  operator()(const shared_ptr<_Tp>& __s) const noexcept
870  {
872  }
873  };
874 
875  // @} relates shared_ptr
876  // @} group pointer_abstractions
877 
878 #if __cplusplus >= 201703L
879  namespace __detail::__variant
880  {
881  template<typename> struct _Never_valueless_alt; // see <variant>
882 
883  // Provide the strong exception-safety guarantee when emplacing a
884  // shared_ptr into a variant.
885  template<typename _Tp>
886  struct _Never_valueless_alt<std::shared_ptr<_Tp>>
888  { };
889 
890  // Provide the strong exception-safety guarantee when emplacing a
891  // weak_ptr into a variant.
892  template<typename _Tp>
893  struct _Never_valueless_alt<std::weak_ptr<_Tp>>
895  { };
896  } // namespace __detail::__variant
897 #endif // C++17
898 
899 _GLIBCXX_END_NAMESPACE_VERSION
900 } // namespace
901 
902 #endif // _SHARED_PTR_H
std::shared_ptr
A smart pointer with reference-counted copy semantics.
Definition: bits/shared_ptr.h:121
std::shared_ptr::operator>=
bool operator>=(const shared_ptr< _Tp > &__a, nullptr_t) noexcept
shared_ptr comparison with nullptr
Definition: bits/shared_ptr.h:543
std::common_type
common_type
Definition: type_traits:2202
std::shared_ptr::const_pointer_cast
shared_ptr< _Tp > const_pointer_cast(const shared_ptr< _Up > &__r) noexcept
Convert type of shared_ptr, via const_cast
Definition: bits/shared_ptr.h:574
shared_ptr_base.h
std::weak_ptr::swap
void swap(weak_ptr< _Tp > &__a, weak_ptr< _Tp > &__b) noexcept
Swap overload for weak_ptr.
Definition: bits/shared_ptr.h:746
std::shared_ptr::get_deleter
_Del * get_deleter(const shared_ptr< _Tp > &__p) noexcept
20.7.2.2.10 shared_ptr get_deleter
Definition: bits/shared_ptr.h:93
std::shared_ptr::operator==
bool operator==(nullptr_t, const shared_ptr< _Tp > &__a) noexcept
shared_ptr comparison with nullptr
Definition: bits/shared_ptr.h:448
std::shared_ptr::shared_ptr
shared_ptr(_Yp *__p, _Deleter __d)
Construct a shared_ptr that owns the pointer __p and the deleter __d.
Definition: bits/shared_ptr.h:176
std::shared_ptr::make_shared
shared_ptr< _Tp > make_shared(_Args &&... __args)
Create an object that is owned by a shared_ptr.
Definition: bits/shared_ptr.h:856
std::shared_ptr::shared_ptr
shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
Construct a shared_ptr that owns a null pointer and the deleter __d.
Definition: bits/shared_ptr.h:232
std
ISO C++ entities toplevel namespace is std.
std::shared_ptr::operator!=
bool operator!=(nullptr_t, const shared_ptr< _Tp > &__a) noexcept
shared_ptr comparison with nullptr
Definition: bits/shared_ptr.h:466
std::basic_ostream
Template class basic_ostream.
Definition: iosfwd:86
std::shared_ptr::operator>=
bool operator>=(nullptr_t, const shared_ptr< _Tp > &__a) noexcept
shared_ptr comparison with nullptr
Definition: bits/shared_ptr.h:549
std::shared_ptr::element_type
typename __shared_ptr< _Tp >::element_type element_type
The type pointed to by the stored pointer, remove_extent_t<_Tp>
Definition: bits/shared_ptr.h:136
std::shared_ptr::operator>
bool operator>(const shared_ptr< _Tp > &__a, const shared_ptr< _Up > &__b) noexcept
Relational operator for shared_ptr objects, compares the stored pointers.
Definition: bits/shared_ptr.h:519
std::shared_ptr::shared_ptr
shared_ptr(shared_ptr< _Yp > &&__r) noexcept
Move-constructs a shared_ptr instance from __r.
Definition: bits/shared_ptr.h:312
std::shared_ptr::shared_ptr
shared_ptr(const shared_ptr< _Yp > &__r, element_type *__p) noexcept
Constructs a shared_ptr instance that stores __p and shares ownership with __r.
Definition: bits/shared_ptr.h:256
std::forward
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:76
std::shared_ptr::operator==
bool operator==(const shared_ptr< _Tp > &__a, nullptr_t) noexcept
shared_ptr comparison with nullptr
Definition: bits/shared_ptr.h:442
std::shared_ptr::shared_ptr
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...
Definition: bits/shared_ptr.h:295
std::unique_ptr
20.7.1.2 unique_ptr for single objects.
Definition: unique_ptr.h:238
std::less
One of the comparison functors.
Definition: stl_function.h:340
std::static_pointer_cast
__shared_ptr< _Tp, _Lp > static_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
static_pointer_cast
Definition: shared_ptr_base.h:1556
std::hash
Primary class template hash.
Definition: typeindex:93
std::shared_ptr::operator!=
bool operator!=(const shared_ptr< _Tp > &__a, nullptr_t) noexcept
shared_ptr comparison with nullptr
Definition: bits/shared_ptr.h:460
std::shared_ptr::dynamic_pointer_cast
shared_ptr< _Tp > dynamic_pointer_cast(const shared_ptr< _Up > &__r) noexcept
Convert type of shared_ptr, via dynamic_cast
Definition: bits/shared_ptr.h:583
std::owner_less
Primary template owner_less.
Definition: bits/shared_ptr.h:752
std::shared_ptr::static_pointer_cast
shared_ptr< _Tp > static_pointer_cast(const shared_ptr< _Up > &__r) noexcept
Convert type of shared_ptr, via static_cast
Definition: bits/shared_ptr.h:565
std::shared_ptr::operator==
bool operator==(const shared_ptr< _Tp > &__a, const shared_ptr< _Up > &__b) noexcept
Equality operator for shared_ptr objects, compares the stored pointers.
Definition: bits/shared_ptr.h:436
std::shared_ptr::shared_ptr
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...
Definition: bits/shared_ptr.h:324
std::shared_ptr::operator>
bool operator>(nullptr_t, const shared_ptr< _Tp > &__a) noexcept
shared_ptr comparison with nullptr
Definition: bits/shared_ptr.h:531
std::shared_ptr::shared_ptr
shared_ptr(nullptr_t __p, _Deleter __d)
Construct a shared_ptr that owns a null pointer and the deleter __d.
Definition: bits/shared_ptr.h:193
std::integral_constant
integral_constant
Definition: type_traits:57
std::shared_ptr::shared_ptr
constexpr shared_ptr(nullptr_t) noexcept
Construct an empty shared_ptr.
Definition: bits/shared_ptr.h:356
std::shared_ptr::shared_ptr
constexpr shared_ptr() noexcept
Construct an empty shared_ptr.
Definition: bits/shared_ptr.h:147
std::enable_if
Define a member typedef type only if a boolean constant is true.
Definition: type_traits:2169
std::shared_ptr::shared_ptr
shared_ptr(_Yp *__p)
Construct a shared_ptr that owns the pointer __p.
Definition: bits/shared_ptr.h:159
std::shared_ptr::shared_ptr
shared_ptr(_Yp *__p, _Deleter __d, _Alloc __a)
Construct a shared_ptr that owns the pointer __p and the deleter __d.
Definition: bits/shared_ptr.h:213
std::shared_ptr::operator>=
bool operator>=(const shared_ptr< _Tp > &__a, const shared_ptr< _Up > &__b) noexcept
Relational operator for shared_ptr objects, compares the stored pointers.
Definition: bits/shared_ptr.h:537
std::allocator
The standard allocator, as per [20.4].
Definition: allocator.h:120
std::enable_shared_from_this
Base class allowing use of member function shared_from_this.
Definition: bits/shared_ptr.h:775
std::shared_ptr::allocate_shared
shared_ptr< _Tp > allocate_shared(const _Alloc &__a, _Args &&... __args)
Create an object that is owned by a shared_ptr.
Definition: bits/shared_ptr.h:841
std::shared_ptr::operator!=
bool operator!=(const shared_ptr< _Tp > &__a, const shared_ptr< _Up > &__b) noexcept
Inequality operator for shared_ptr objects, compares the stored pointers.
Definition: bits/shared_ptr.h:454
std::shared_ptr::swap
void swap(shared_ptr< _Tp > &__a, shared_ptr< _Tp > &__b) noexcept
Swap overload for shared_ptr.
Definition: bits/shared_ptr.h:557
std::auto_ptr
A simple smart pointer providing strict ownership semantics.
Definition: auto_ptr.h:89
std::shared_ptr::shared_ptr
shared_ptr(shared_ptr &&__r) noexcept
Move-constructs a shared_ptr instance from __r.
Definition: bits/shared_ptr.h:303
std::const_pointer_cast
__shared_ptr< _Tp, _Lp > const_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
const_pointer_cast
Definition: shared_ptr_base.h:1569
std::weak_ptr
A non-owning observer for a pointer owned by a shared_ptr.
Definition: bits/shared_ptr.h:669
std::dynamic_pointer_cast
__shared_ptr< _Tp, _Lp > dynamic_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
dynamic_pointer_cast
Definition: shared_ptr_base.h:1582
std::is_assignable
is_assignable
Definition: type_traits:1057
std::is_constructible
is_constructible
Definition: type_traits:906
std::shared_ptr::operator>
bool operator>(const shared_ptr< _Tp > &__a, nullptr_t) noexcept
shared_ptr comparison with nullptr
Definition: bits/shared_ptr.h:525
std::move
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:101