libstdc++: shared_ptr.h Source File

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-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
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/iosfwd.h> // std::basic_ostream
53#include <bits/shared_ptr_base.h>
54
55namespace std _GLIBCXX_VISIBILITY(default)
56{
57_GLIBCXX_BEGIN_NAMESPACE_VERSION
58
59 /**
60 * @addtogroup pointer_abstractions
61 * @{
62 */
63
64 // 20.7.2.2.11 shared_ptr I/O
65
66 /// Write the stored pointer to an ostream.
67 /// @relates shared_ptr
68 template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
69 inline std::basic_ostream<_Ch, _Tr>&
70 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
71 const __shared_ptr<_Tp, _Lp>& __p)
72 {
73 __os << __p.get();
74 return __os;
75 }
76
77 template<typename _Del, typename _Tp, _Lock_policy _Lp>
78 inline _Del*
79 get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
80 {
81#if __cpp_rtti
82 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
83#else
84 return 0;
85#endif
86 }
87
88 /// 20.7.2.2.10 shared_ptr get_deleter
89
90 /// If `__p` has a deleter of type `_Del`, return a pointer to it.
91 /// @relates shared_ptr
92 template<typename _Del, typename _Tp>
93 inline _Del*
94 get_deleter(const shared_ptr<_Tp>& __p) noexcept
95 {
96#if __cpp_rtti
97 return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
98#else
99 return 0;
100#endif
101 }
102
103 /// @cond undocumented
104
105 // Constraint for overloads taking non-array types.
106#if __cpp_concepts && __glibcxx_type_trait_variable_templates
107 template<typename _Tp>
108 requires (!is_array_v<_Tp>)
109 using _NonArray = _Tp;
110#else
111 template<typename _Tp>
112 using _NonArray = __enable_if_t<!is_array<_Tp>::value, _Tp>;
113#endif
114
115#if __glibcxx_shared_ptr_arrays >= 201707L
116 // Constraint for overloads taking array types with unknown bound, U[].
117 template<typename _Tp>
118 requires is_array_v<_Tp> && (extent_v<_Tp> == 0)
119 using _UnboundedArray = _Tp;
120
121 // Constraint for overloads taking array types with known bound, U[N].
122 template<typename _Tp>
123 requires (extent_v<_Tp> != 0)
124 using _BoundedArray = _Tp;
125
126#if __glibcxx_smart_ptr_for_overwrite
127 // Constraint for overloads taking either non-array or bounded array, U[N].
128 template<typename _Tp>
129 requires (!is_array_v<_Tp>) || (extent_v<_Tp> != 0)
130 using _NotUnboundedArray = _Tp;
131#endif // smart_ptr_for_overwrite
132#endif // shared_ptr_arrays
133
134 /// @endcond
135
136 /**
137 * @brief A smart pointer with reference-counted copy semantics.
138 * @headerfile memory
139 * @since C++11
140 *
141 * A `shared_ptr` object is either empty or _owns_ a pointer passed
142 * to the constructor. Copies of a `shared_ptr` share ownership of
143 * the same pointer. When the last `shared_ptr` that owns the pointer
144 * is destroyed or reset, the owned pointer is freed (either by `delete`
145 * or by invoking a custom deleter that was passed to the constructor).
146 *
147 * A `shared_ptr` also stores another pointer, which is usually
148 * (but not always) the same pointer as it owns. The stored pointer
149 * can be retrieved by calling the `get()` member function.
150 *
151 * The equality and relational operators for `shared_ptr` only compare
152 * the stored pointer returned by `get()`, not the owned pointer.
153 * To test whether two `shared_ptr` objects share ownership of the same
154 * pointer see `std::shared_ptr::owner_before` and `std::owner_less`.
155 */
156 template<typename _Tp>
157 class shared_ptr : public __shared_ptr<_Tp>
158 {
159 template<typename... _Args>
160 using _Constructible = typename enable_if<
161 is_constructible<__shared_ptr<_Tp>, _Args...>::value
162 >::type;
163
164 template<typename _Arg>
165 using _Assignable = typename enable_if<
166 is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr&
167 >::type;
168
169 public:
170
171 /// The type pointed to by the stored pointer, remove_extent_t<_Tp>
172 using element_type = typename __shared_ptr<_Tp>::element_type;
173
174#ifdef __glibcxx_shared_ptr_weak_type // C++ >= 17 && HOSTED
175 /// The corresponding weak_ptr type for this shared_ptr
176 /// @since C++17
177 using weak_type = weak_ptr<_Tp>;
178#endif
179 /**
180 * @brief Construct an empty %shared_ptr.
181 * @post use_count()==0 && get()==0
182 */
183 constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
184
185 shared_ptr(const shared_ptr&) noexcept = default; ///< Copy constructor
186
187 /**
188 * @brief Construct a %shared_ptr that owns the pointer @a __p.
189 * @param __p A pointer that is convertible to element_type*.
190 * @post use_count() == 1 && get() == __p
191 * @throw std::bad_alloc, in which case @c delete @a __p is called.
192 */
193 template<typename _Yp, typename = _Constructible<_Yp*>>
194 explicit
195 shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }
196
197 /**
198 * @brief Construct a %shared_ptr that owns the pointer @a __p
199 * and the deleter @a __d.
200 * @param __p A pointer.
201 * @param __d A deleter.
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
207 *
208 * __shared_ptr will release __p by calling __d(__p)
209 */
210 template<typename _Yp, typename _Deleter,
211 typename = _Constructible<_Yp*, _Deleter>>
212 shared_ptr(_Yp* __p, _Deleter __d)
213 : __shared_ptr<_Tp>(__p, std::move(__d)) { }
214
215 /**
216 * @brief Construct a %shared_ptr that owns a null pointer
217 * and the deleter @a __d.
218 * @param __p A null pointer constant.
219 * @param __d A deleter.
220 * @post use_count() == 1 && get() == __p
221 * @throw std::bad_alloc, in which case @a __d(__p) is called.
222 *
223 * Requirements: _Deleter's copy constructor and destructor must
224 * not throw
225 *
226 * The last owner will call __d(__p)
227 */
228 template<typename _Deleter>
229 shared_ptr(nullptr_t __p, _Deleter __d)
230 : __shared_ptr<_Tp>(__p, std::move(__d)) { }
231
232 /**
233 * @brief Construct a %shared_ptr that owns the pointer @a __p
234 * and the deleter @a __d.
235 * @param __p A pointer.
236 * @param __d A deleter.
237 * @param __a An allocator.
238 * @post use_count() == 1 && get() == __p
239 * @throw std::bad_alloc, in which case @a __d(__p) is called.
240 *
241 * Requirements: _Deleter's copy constructor and destructor must
242 * not throw _Alloc's copy constructor and destructor must not
243 * throw.
244 *
245 * __shared_ptr will release __p by calling __d(__p)
246 */
247 template<typename _Yp, typename _Deleter, typename _Alloc,
248 typename = _Constructible<_Yp*, _Deleter, _Alloc>>
249 shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
250 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
251
252 /**
253 * @brief Construct a %shared_ptr that owns a null pointer
254 * and the deleter @a __d.
255 * @param __p A null pointer constant.
256 * @param __d A deleter.
257 * @param __a An allocator.
258 * @post use_count() == 1 && get() == __p
259 * @throw std::bad_alloc, in which case @a __d(__p) is called.
260 *
261 * Requirements: _Deleter's copy constructor and destructor must
262 * not throw _Alloc's copy constructor and destructor must not
263 * throw.
264 *
265 * The last owner will call __d(__p)
266 */
267 template<typename _Deleter, typename _Alloc>
268 shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
269 : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
270
271 // Aliasing constructor
272
273 /**
274 * @brief Constructs a `shared_ptr` instance that stores `__p`
275 * and shares ownership with `__r`.
276 * @param __r A `shared_ptr`.
277 * @param __p A pointer that will remain valid while `*__r` is valid.
278 * @post `get() == __p && use_count() == __r.use_count()`
279 *
280 * This can be used to construct a `shared_ptr` to a sub-object
281 * of an object managed by an existing `shared_ptr`. The complete
282 * object will remain valid while any `shared_ptr` owns it, even
283 * if they don't store a pointer to the complete object.
284 *
285 * @code
286 * shared_ptr<pair<int,int>> pii(new pair<int,int>());
287 * shared_ptr<int> pi(pii, &pii->first);
288 * assert(pii.use_count() == 2);
289 * @endcode
290 */
291 template<typename _Yp>
292 shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
293 : __shared_ptr<_Tp>(__r, __p) { }
294
295#if __cplusplus > 201703L
296 // _GLIBCXX_RESOLVE_LIB_DEFECTS
297 // 2996. Missing rvalue overloads for shared_ptr operations
298 /**
299 * @brief Constructs a `shared_ptr` instance that stores `__p`
300 * and shares ownership with `__r`.
301 * @param __r A `shared_ptr`.
302 * @param __p A pointer that will remain valid while `*__r` is valid.
303 * @post `get() == __p && !__r.use_count() && !__r.get()`
304 * @since C++17
305 *
306 * This can be used to construct a `shared_ptr` to a sub-object
307 * of an object managed by an existing `shared_ptr`. The complete
308 * object will remain valid while any `shared_ptr` owns it, even
309 * if they don't store a pointer to the complete object.
310 *
311 * @code
312 * shared_ptr<pair<int,int>> pii(new pair<int,int>());
313 * shared_ptr<int> pi1(pii, &pii->first);
314 * assert(pii.use_count() == 2);
315 * shared_ptr<int> pi2(std::move(pii), &pii->second);
316 * assert(pii.use_count() == 0);
317 * @endcode
318 */
319 template<typename _Yp>
320 shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept
321 : __shared_ptr<_Tp>(std::move(__r), __p) { }
322#endif
323 /**
324 * @brief If @a __r is empty, constructs an empty %shared_ptr;
325 * otherwise construct a %shared_ptr that shares ownership
326 * with @a __r.
327 * @param __r A %shared_ptr.
328 * @post get() == __r.get() && use_count() == __r.use_count()
329 */
330 template<typename _Yp,
331 typename = _Constructible<const shared_ptr<_Yp>&>>
332 shared_ptr(const shared_ptr<_Yp>& __r) noexcept
333 : __shared_ptr<_Tp>(__r) { }
334
335 /**
336 * @brief Move-constructs a %shared_ptr instance from @a __r.
337 * @param __r A %shared_ptr rvalue.
338 * @post *this contains the old value of @a __r, @a __r is empty.
339 */
340 shared_ptr(shared_ptr&& __r) noexcept
341 : __shared_ptr<_Tp>(std::move(__r)) { }
342
343 /**
344 * @brief Move-constructs a %shared_ptr instance from @a __r.
345 * @param __r A %shared_ptr rvalue.
346 * @post *this contains the old value of @a __r, @a __r is empty.
347 */
348 template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
349 shared_ptr(shared_ptr<_Yp>&& __r) noexcept
350 : __shared_ptr<_Tp>(std::move(__r)) { }
351
352 /**
353 * @brief Constructs a %shared_ptr that shares ownership with @a __r
354 * and stores a copy of the pointer stored in @a __r.
355 * @param __r A weak_ptr.
356 * @post use_count() == __r.use_count()
357 * @throw bad_weak_ptr when __r.expired(),
358 * in which case the constructor has no effect.
359 */
360 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
361 explicit shared_ptr(const weak_ptr<_Yp>& __r)
362 : __shared_ptr<_Tp>(__r) { }
363
364#if _GLIBCXX_USE_DEPRECATED
365#pragma GCC diagnostic push
366#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
367 template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>
368 shared_ptr(auto_ptr<_Yp>&& __r);
369#pragma GCC diagnostic pop
370#endif
371
372 // _GLIBCXX_RESOLVE_LIB_DEFECTS
373 // 2399. shared_ptr's constructor from unique_ptr should be constrained
374 template<typename _Yp, typename _Del,
375 typename = _Constructible<unique_ptr<_Yp, _Del>>>
376 shared_ptr(unique_ptr<_Yp, _Del>&& __r)
377 : __shared_ptr<_Tp>(std::move(__r)) { }
378
379#if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
380 // This non-standard constructor exists to support conversions that
381 // were possible in C++11 and C++14 but are ill-formed in C++17.
382 // If an exception is thrown this constructor has no effect.
383 template<typename _Yp, typename _Del,
384 _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
385 shared_ptr(unique_ptr<_Yp, _Del>&& __r)
386 : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }
387#endif
388
389 /**
390 * @brief Construct an empty %shared_ptr.
391 * @post use_count() == 0 && get() == nullptr
392 */
393 constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
394
395 shared_ptr& operator=(const shared_ptr&) noexcept = default;
396
397 template<typename _Yp>
398 _Assignable<const shared_ptr<_Yp>&>
399 operator=(const shared_ptr<_Yp>& __r) noexcept
400 {
401 this->__shared_ptr<_Tp>::operator=(__r);
402 return *this;
403 }
404
405#if _GLIBCXX_USE_DEPRECATED
406#pragma GCC diagnostic push
407#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
408 template<typename _Yp>
409 _Assignable<auto_ptr<_Yp>>
410 operator=(auto_ptr<_Yp>&& __r)
411 {
412 this->__shared_ptr<_Tp>::operator=(std::move(__r));
413 return *this;
414 }
415#pragma GCC diagnostic pop
416#endif
417
418 shared_ptr&
419 operator=(shared_ptr&& __r) noexcept
420 {
421 this->__shared_ptr<_Tp>::operator=(std::move(__r));
422 return *this;
423 }
424
425 template<class _Yp>
426 _Assignable<shared_ptr<_Yp>>
427 operator=(shared_ptr<_Yp>&& __r) noexcept
428 {
429 this->__shared_ptr<_Tp>::operator=(std::move(__r));
430 return *this;
431 }
432
433 template<typename _Yp, typename _Del>
434 _Assignable<unique_ptr<_Yp, _Del>>
435 operator=(unique_ptr<_Yp, _Del>&& __r)
436 {
437 this->__shared_ptr<_Tp>::operator=(std::move(__r));
438 return *this;
439 }
440
441 private:
442 // This constructor is non-standard, it is used by allocate_shared.
443 template<typename _Alloc, typename... _Args>
444 shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
445 : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
446 { }
447
448 template<typename _Yp, typename _Alloc, typename... _Args>
449 friend shared_ptr<_NonArray<_Yp>>
450 allocate_shared(const _Alloc&, _Args&&...);
451
452 template<typename _Yp, typename... _Args>
453 friend shared_ptr<_NonArray<_Yp>>
454 make_shared(_Args&&...);
455
456#if __glibcxx_shared_ptr_arrays >= 201707L
457 // This constructor is non-standard, it is used by allocate_shared<T[]>.
458 template<typename _Alloc, typename _Init = const remove_extent_t<_Tp>*>
459 shared_ptr(const _Sp_counted_array_base<_Alloc>& __a,
460 _Init __init = nullptr)
461 : __shared_ptr<_Tp>(__a, __init)
462 { }
463
464 template<typename _Yp, typename _Alloc>
465 friend shared_ptr<_UnboundedArray<_Yp>>
466 allocate_shared(const _Alloc&, size_t);
467
468 template<typename _Yp>
469 friend shared_ptr<_UnboundedArray<_Yp>>
470 make_shared(size_t);
471
472 template<typename _Yp, typename _Alloc>
473 friend shared_ptr<_UnboundedArray<_Yp>>
474 allocate_shared(const _Alloc&, size_t, const remove_extent_t<_Yp>&);
475
476 template<typename _Yp>
477 friend shared_ptr<_UnboundedArray<_Yp>>
478 make_shared(size_t, const remove_extent_t<_Yp>&);
479
480 template<typename _Yp, typename _Alloc>
481 friend shared_ptr<_BoundedArray<_Yp>>
482 allocate_shared(const _Alloc&);
483
484 template<typename _Yp>
485 friend shared_ptr<_BoundedArray<_Yp>>
486 make_shared();
487
488 template<typename _Yp, typename _Alloc>
489 friend shared_ptr<_BoundedArray<_Yp>>
490 allocate_shared(const _Alloc&, const remove_extent_t<_Yp>&);
491
492 template<typename _Yp>
493 friend shared_ptr<_BoundedArray<_Yp>>
494 make_shared(const remove_extent_t<_Yp>&);
495
496#if __glibcxx_smart_ptr_for_overwrite
497 template<typename _Yp, typename _Alloc>
498 friend shared_ptr<_NotUnboundedArray<_Yp>>
499 allocate_shared_for_overwrite(const _Alloc&);
500
501 template<typename _Yp>
502 friend shared_ptr<_NotUnboundedArray<_Yp>>
503 make_shared_for_overwrite();
504
505 template<typename _Yp, typename _Alloc>
506 friend shared_ptr<_UnboundedArray<_Yp>>
507 allocate_shared_for_overwrite(const _Alloc&, size_t);
508
509 template<typename _Yp>
510 friend shared_ptr<_UnboundedArray<_Yp>>
511 make_shared_for_overwrite(size_t);
512#endif
513#endif
514
515 // This constructor is non-standard, it is used by weak_ptr::lock().
516 shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t) noexcept
517 : __shared_ptr<_Tp>(__r, std::nothrow) { }
518
519 friend class weak_ptr<_Tp>;
520 };
521
522#if __cpp_deduction_guides >= 201606
523 template<typename _Tp>
524 shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
525 template<typename _Tp, typename _Del>
526 shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>;
527#endif
528
529 // 20.7.2.2.7 shared_ptr comparisons
530
531 /// @relates shared_ptr @{
532
533 /// Equality operator for shared_ptr objects, compares the stored pointers
534 template<typename _Tp, typename _Up>
535 _GLIBCXX_NODISCARD inline bool
536 operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
537 { return __a.get() == __b.get(); }
538
539 /// shared_ptr comparison with nullptr
540 template<typename _Tp>
541 _GLIBCXX_NODISCARD inline bool
542 operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
543 { return !__a; }
544
545#ifdef __cpp_lib_three_way_comparison
546 template<typename _Tp, typename _Up>
547 inline strong_ordering
548 operator<=>(const shared_ptr<_Tp>& __a,
549 const shared_ptr<_Up>& __b) noexcept
550 { return compare_three_way()(__a.get(), __b.get()); }
551
552 template<typename _Tp>
553 inline strong_ordering
554 operator<=>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
555 {
556 using pointer = typename shared_ptr<_Tp>::element_type*;
557 return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
558 }
559#else
560 /// shared_ptr comparison with nullptr
561 template<typename _Tp>
562 _GLIBCXX_NODISCARD inline bool
563 operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
564 { return !__a; }
565
566 /// Inequality operator for shared_ptr objects, compares the stored pointers
567 template<typename _Tp, typename _Up>
568 _GLIBCXX_NODISCARD inline bool
569 operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
570 { return __a.get() != __b.get(); }
571
572 /// shared_ptr comparison with nullptr
573 template<typename _Tp>
574 _GLIBCXX_NODISCARD inline bool
575 operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
576 { return (bool)__a; }
577
578 /// shared_ptr comparison with nullptr
579 template<typename _Tp>
580 _GLIBCXX_NODISCARD inline bool
581 operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
582 { return (bool)__a; }
583
584 /// Relational operator for shared_ptr objects, compares the stored pointers
585 template<typename _Tp, typename _Up>
586 _GLIBCXX_NODISCARD inline bool
587 operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
588 {
589 using _Tp_elt = typename shared_ptr<_Tp>::element_type;
590 using _Up_elt = typename shared_ptr<_Up>::element_type;
591 using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
592 return less<_Vp>()(__a.get(), __b.get());
593 }
594
595 /// shared_ptr comparison with nullptr
596 template<typename _Tp>
597 _GLIBCXX_NODISCARD inline bool
598 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
599 {
600 using _Tp_elt = typename shared_ptr<_Tp>::element_type;
601 return less<_Tp_elt*>()(__a.get(), nullptr);
602 }
603
604 /// shared_ptr comparison with nullptr
605 template<typename _Tp>
606 _GLIBCXX_NODISCARD inline bool
607 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
608 {
609 using _Tp_elt = typename shared_ptr<_Tp>::element_type;
610 return less<_Tp_elt*>()(nullptr, __a.get());
611 }
612
613 /// Relational operator for shared_ptr objects, compares the stored pointers
614 template<typename _Tp, typename _Up>
615 _GLIBCXX_NODISCARD inline bool
616 operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
617 { return !(__b < __a); }
618
619 /// shared_ptr comparison with nullptr
620 template<typename _Tp>
621 _GLIBCXX_NODISCARD inline bool
622 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
623 { return !(nullptr < __a); }
624
625 /// shared_ptr comparison with nullptr
626 template<typename _Tp>
627 _GLIBCXX_NODISCARD inline bool
628 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
629 { return !(__a < nullptr); }
630
631 /// Relational operator for shared_ptr objects, compares the stored pointers
632 template<typename _Tp, typename _Up>
633 _GLIBCXX_NODISCARD inline bool
634 operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
635 { return (__b < __a); }
636
637 /// shared_ptr comparison with nullptr
638 template<typename _Tp>
639 _GLIBCXX_NODISCARD inline bool
640 operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
641 { return nullptr < __a; }
642
643 /// shared_ptr comparison with nullptr
644 template<typename _Tp>
645 _GLIBCXX_NODISCARD inline bool
646 operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
647 { return __a < nullptr; }
648
649 /// Relational operator for shared_ptr objects, compares the stored pointers
650 template<typename _Tp, typename _Up>
651 _GLIBCXX_NODISCARD inline bool
652 operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
653 { return !(__a < __b); }
654
655 /// shared_ptr comparison with nullptr
656 template<typename _Tp>
657 _GLIBCXX_NODISCARD inline bool
658 operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
659 { return !(__a < nullptr); }
660
661 /// shared_ptr comparison with nullptr
662 template<typename _Tp>
663 _GLIBCXX_NODISCARD inline bool
664 operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
665 { return !(nullptr < __a); }
666#endif
667
668 // 20.7.2.2.8 shared_ptr specialized algorithms.
669
670 /// Swap overload for shared_ptr
671 template<typename _Tp>
672 inline void
673 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
674 { __a.swap(__b); }
675
676 // 20.7.2.2.9 shared_ptr casts.
677
678 /// Convert type of `shared_ptr`, via `static_cast`
679 template<typename _Tp, typename _Up>
680 inline shared_ptr<_Tp>
681 static_pointer_cast(const shared_ptr<_Up>& __r) noexcept
682 {
683 using _Sp = shared_ptr<_Tp>;
684 return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
685 }
686
687 /// Convert type of `shared_ptr`, via `const_cast`
688 template<typename _Tp, typename _Up>
689 inline shared_ptr<_Tp>
690 const_pointer_cast(const shared_ptr<_Up>& __r) noexcept
691 {
692 using _Sp = shared_ptr<_Tp>;
693 return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
694 }
695
696 /// Convert type of `shared_ptr`, via `dynamic_cast`
697 template<typename _Tp, typename _Up>
698 inline shared_ptr<_Tp>
699 dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept
700 {
701 using _Sp = shared_ptr<_Tp>;
702 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
703 return _Sp(__r, __p);
704 return _Sp();
705 }
706
707#if __cplusplus >= 201703L
708 /// Convert type of `shared_ptr`, via `reinterpret_cast`
709 /// @since C++17
710 template<typename _Tp, typename _Up>
711 inline shared_ptr<_Tp>
712 reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
713 {
714 using _Sp = shared_ptr<_Tp>;
715 return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
716 }
717
718#if __cplusplus > 201703L
719 // _GLIBCXX_RESOLVE_LIB_DEFECTS
720 // 2996. Missing rvalue overloads for shared_ptr operations
721
722 /// Convert type of `shared_ptr` rvalue, via `static_cast`
723 /// @since C++20
724 template<typename _Tp, typename _Up>
725 inline shared_ptr<_Tp>
726 static_pointer_cast(shared_ptr<_Up>&& __r) noexcept
727 {
728 using _Sp = shared_ptr<_Tp>;
729 return _Sp(std::move(__r),
730 static_cast<typename _Sp::element_type*>(__r.get()));
731 }
732
733 /// Convert type of `shared_ptr` rvalue, via `const_cast`
734 /// @since C++20
735 template<typename _Tp, typename _Up>
736 inline shared_ptr<_Tp>
737 const_pointer_cast(shared_ptr<_Up>&& __r) noexcept
738 {
739 using _Sp = shared_ptr<_Tp>;
740 return _Sp(std::move(__r),
741 const_cast<typename _Sp::element_type*>(__r.get()));
742 }
743
744 /// Convert type of `shared_ptr` rvalue, via `dynamic_cast`
745 /// @since C++20
746 template<typename _Tp, typename _Up>
747 inline shared_ptr<_Tp>
748 dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept
749 {
750 using _Sp = shared_ptr<_Tp>;
751 if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
752 return _Sp(std::move(__r), __p);
753 return _Sp();
754 }
755
756 /// Convert type of `shared_ptr` rvalue, via `reinterpret_cast`
757 /// @since C++20
758 template<typename _Tp, typename _Up>
759 inline shared_ptr<_Tp>
760 reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept
761 {
762 using _Sp = shared_ptr<_Tp>;
763 return _Sp(std::move(__r),
764 reinterpret_cast<typename _Sp::element_type*>(__r.get()));
765 }
766#endif // C++20
767#endif // C++17
768
769 /// @}
770
771 /**
772 * @brief A non-owning observer for a pointer owned by a shared_ptr
773 * @headerfile memory
774 * @since C++11
775 *
776 * A weak_ptr provides a safe alternative to a raw pointer when you want
777 * a non-owning reference to an object that is managed by a shared_ptr.
778 *
779 * Unlike a raw pointer, a weak_ptr can be converted to a new shared_ptr
780 * that shares ownership with every other shared_ptr that already owns
781 * the pointer. In other words you can upgrade from a non-owning "weak"
782 * reference to an owning shared_ptr, without having access to any of
783 * the existing shared_ptr objects.
784 *
785 * Also unlike a raw pointer, a weak_ptr does not become "dangling" after
786 * the object it points to has been destroyed. Instead, a weak_ptr
787 * becomes _expired_ and can no longer be converted to a shared_ptr that
788 * owns the freed pointer, so you cannot accidentally access the pointed-to
789 * object after it has been destroyed.
790 */
791 template<typename _Tp>
792 class weak_ptr : public __weak_ptr<_Tp>
793 {
794 template<typename _Arg>
795 using _Constructible = typename enable_if<
796 is_constructible<__weak_ptr<_Tp>, _Arg>::value
797 >::type;
798
799 template<typename _Arg>
800 using _Assignable = typename enable_if<
801 is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&
802 >::type;
803
804 public:
805 constexpr weak_ptr() noexcept = default;
806
807 template<typename _Yp,
808 typename = _Constructible<const shared_ptr<_Yp>&>>
809 weak_ptr(const shared_ptr<_Yp>& __r) noexcept
810 : __weak_ptr<_Tp>(__r) { }
811
812 weak_ptr(const weak_ptr&) noexcept = default;
813
814 template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
815 weak_ptr(const weak_ptr<_Yp>& __r) noexcept
816 : __weak_ptr<_Tp>(__r) { }
817
818 weak_ptr(weak_ptr&&) noexcept = default;
819
820 template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>
821 weak_ptr(weak_ptr<_Yp>&& __r) noexcept
822 : __weak_ptr<_Tp>(std::move(__r)) { }
823
824 weak_ptr&
825 operator=(const weak_ptr& __r) noexcept = default;
826
827 template<typename _Yp>
828 _Assignable<const weak_ptr<_Yp>&>
829 operator=(const weak_ptr<_Yp>& __r) noexcept
830 {
831 this->__weak_ptr<_Tp>::operator=(__r);
832 return *this;
833 }
834
835 template<typename _Yp>
836 _Assignable<const shared_ptr<_Yp>&>
837 operator=(const shared_ptr<_Yp>& __r) noexcept
838 {
839 this->__weak_ptr<_Tp>::operator=(__r);
840 return *this;
841 }
842
843 weak_ptr&
844 operator=(weak_ptr&& __r) noexcept = default;
845
846 template<typename _Yp>
847 _Assignable<weak_ptr<_Yp>>
848 operator=(weak_ptr<_Yp>&& __r) noexcept
849 {
850 this->__weak_ptr<_Tp>::operator=(std::move(__r));
851 return *this;
852 }
853
854 shared_ptr<_Tp>
855 lock() const noexcept
856 { return shared_ptr<_Tp>(*this, std::nothrow); }
857 };
858
859#if __cpp_deduction_guides >= 201606
860 template<typename _Tp>
861 weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
862#endif
863
864 // 20.7.2.3.6 weak_ptr specialized algorithms.
865 /// Swap overload for weak_ptr
866 /// @relates weak_ptr
867 template<typename _Tp>
868 inline void
869 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
870 { __a.swap(__b); }
871
872
873 /// Primary template owner_less
874 template<typename _Tp = void>
875 struct owner_less;
876
877 /// Void specialization of owner_less compares either shared_ptr or weak_ptr
878 template<>
879 struct owner_less<void> : _Sp_owner_less<void, void>
880 { };
881
882 /// Partial specialization of owner_less for shared_ptr.
883 template<typename _Tp>
884 struct owner_less<shared_ptr<_Tp>>
885 : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
886 { };
887
888 /// Partial specialization of owner_less for weak_ptr.
889 template<typename _Tp>
890 struct owner_less<weak_ptr<_Tp>>
891 : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
892 { };
893
894#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26
895
896 /**
897 * @brief Provides ownership-based hashing.
898 * @headerfile memory
899 * @since C++26
900 */
901 struct owner_hash
902 {
903 template<typename _Tp>
904 size_t
905 operator()(const shared_ptr<_Tp>& __s) const noexcept
906 { return __s.owner_hash(); }
907
908 template<typename _Tp>
909 size_t
910 operator()(const weak_ptr<_Tp>& __s) const noexcept
911 { return __s.owner_hash(); }
912
913 using is_transparent = void;
914 };
915
916 /**
917 * @brief Provides ownership-based mixed equality comparisons of
918 * shared and weak pointers.
919 * @headerfile memory
920 * @since C++26
921 */
922 struct owner_equal
923 {
924 template<typename _Tp1, typename _Tp2>
925 bool
926 operator()(const shared_ptr<_Tp1>& __lhs,
927 const shared_ptr<_Tp2>& __rhs) const noexcept
928 { return __lhs.owner_equal(__rhs); }
929
930 template<typename _Tp1, typename _Tp2>
931 bool
932 operator()(const shared_ptr<_Tp1>& __lhs,
933 const weak_ptr<_Tp2>& __rhs) const noexcept
934 { return __lhs.owner_equal(__rhs); }
935
936 template<typename _Tp1, typename _Tp2>
937 bool
938 operator()(const weak_ptr<_Tp1>& __lhs,
939 const shared_ptr<_Tp2>& __rhs) const noexcept
940 { return __lhs.owner_equal(__rhs); }
941
942 template<typename _Tp1, typename _Tp2>
943 bool
944 operator()(const weak_ptr<_Tp1>& __lhs,
945 const weak_ptr<_Tp2>& __rhs) const noexcept
946 { return __lhs.owner_equal(__rhs); }
947
948 using is_transparent = void;
949 };
950#endif
951
952 /**
953 * @brief Base class allowing use of the member function `shared_from_this`.
954 * @headerfile memory
955 * @since C++11
956 */
957 template<typename _Tp>
958 class enable_shared_from_this
959 {
960 protected:
961 constexpr enable_shared_from_this() noexcept { }
962
963 enable_shared_from_this(const enable_shared_from_this&) noexcept { }
964
965 enable_shared_from_this&
966 operator=(const enable_shared_from_this&) noexcept
967 { return *this; }
968
969 ~enable_shared_from_this() { }
970
971 public:
972 shared_ptr<_Tp>
973 shared_from_this()
974 { return shared_ptr<_Tp>(this->_M_weak_this); }
975
976 shared_ptr<const _Tp>
977 shared_from_this() const
978 { return shared_ptr<const _Tp>(this->_M_weak_this); }
979
980#ifdef __glibcxx_enable_shared_from_this // C++ >= 17 && HOSTED
981 /** @{
982 * Get a `weak_ptr` referring to the object that has `*this` as its base.
983 * @since C++17
984 */
985 weak_ptr<_Tp>
986 weak_from_this() noexcept
987 { return this->_M_weak_this; }
988
989 weak_ptr<const _Tp>
990 weak_from_this() const noexcept
991 { return this->_M_weak_this; }
992 /// @}
993#endif
994
995 private:
996 template<typename _Tp1>
997 void
998 _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
999 { _M_weak_this._M_assign(__p, __n); }
1000
1001 // Found by ADL when this is an associated class.
1002 friend const enable_shared_from_this*
1003 __enable_shared_from_this_base(const __shared_count<>&,
1004 const enable_shared_from_this* __p)
1005 { return __p; }
1006
1007 template<typename, _Lock_policy>
1008 friend class __shared_ptr;
1009
1010 mutable weak_ptr<_Tp> _M_weak_this;
1011 };
1012
1013 /// @relates shared_ptr @{
1014
1015 /**
1016 * @brief Create an object that is owned by a shared_ptr.
1017 * @param __a An allocator.
1018 * @param __args Arguments for the @a _Tp object's constructor.
1019 * @return A shared_ptr that owns the newly created object.
1020 * @throw An exception thrown from @a _Alloc::allocate or from the
1021 * constructor of @a _Tp.
1022 *
1023 * A copy of @a __a will be used to allocate memory for the shared_ptr
1024 * and the new object.
1025 */
1026 template<typename _Tp, typename _Alloc, typename... _Args>
1027 inline shared_ptr<_NonArray<_Tp>>
1028 allocate_shared(const _Alloc& __a, _Args&&... __args)
1029 {
1030 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
1031 std::forward<_Args>(__args)...);
1032 }
1033
1034 /**
1035 * @brief Create an object that is owned by a shared_ptr.
1036 * @param __args Arguments for the @a _Tp object's constructor.
1037 * @return A shared_ptr that owns the newly created object.
1038 * @throw std::bad_alloc, or an exception thrown from the
1039 * constructor of @a _Tp.
1040 */
1041 template<typename _Tp, typename... _Args>
1042 inline shared_ptr<_NonArray<_Tp>>
1043 make_shared(_Args&&... __args)
1044 {
1045 using _Alloc = allocator<void>;
1046 _Alloc __a;
1047 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
1048 std::forward<_Args>(__args)...);
1049 }
1050
1051#if __glibcxx_shared_ptr_arrays >= 201707L
1052 /// @cond undocumented
1053 template<typename _Tp, typename _Alloc = allocator<void>>
1054 auto
1055 __make_shared_arr_tag(size_t __n, const _Alloc& __a = _Alloc()) noexcept
1056 {
1057 using _Up = remove_all_extents_t<_Tp>;
1058 using _UpAlloc = __alloc_rebind<_Alloc, _Up>;
1059 size_t __s = sizeof(remove_extent_t<_Tp>) / sizeof(_Up);
1060 if (__builtin_mul_overflow(__s, __n, &__n))
1061 std::__throw_bad_array_new_length();
1062 return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};
1063 }
1064 /// @endcond
1065
1066 template<typename _Tp, typename _Alloc>
1067 inline shared_ptr<_UnboundedArray<_Tp>>
1068 allocate_shared(const _Alloc& __a, size_t __n)
1069 {
1070 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n, __a));
1071 }
1072
1073 template<typename _Tp>
1074 inline shared_ptr<_UnboundedArray<_Tp>>
1075 make_shared(size_t __n)
1076 {
1077 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n));
1078 }
1079
1080 template<typename _Tp, typename _Alloc>
1081 inline shared_ptr<_UnboundedArray<_Tp>>
1082 allocate_shared(const _Alloc& __a, size_t __n,
1083 const remove_extent_t<_Tp>& __u)
1084 {
1085 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n, __a),
1086 std::__addressof(__u));
1087 }
1088
1089 template<typename _Tp>
1090 inline shared_ptr<_UnboundedArray<_Tp>>
1091 make_shared(size_t __n, const remove_extent_t<_Tp>& __u)
1092 {
1093 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n),
1094 std::__addressof(__u));
1095 }
1096
1097 /// @cond undocumented
1098 template<typename _Tp, typename _Alloc = allocator<void>>
1099 auto
1100 __make_shared_arrN_tag(const _Alloc& __a = _Alloc()) noexcept
1101 {
1102 using _Up = remove_all_extents_t<_Tp>;
1103 using _UpAlloc = __alloc_rebind<_Alloc, _Up>;
1104 size_t __n = sizeof(_Tp) / sizeof(_Up);
1105 return _Sp_counted_array_base<_UpAlloc>{_UpAlloc(__a), __n};
1106 }
1107 /// @endcond
1108
1109 template<typename _Tp, typename _Alloc>
1110 inline shared_ptr<_BoundedArray<_Tp>>
1111 allocate_shared(const _Alloc& __a)
1112 {
1113 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(__a));
1114 }
1115
1116 template<typename _Tp>
1117 inline shared_ptr<_BoundedArray<_Tp>>
1118 make_shared()
1119 {
1120 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>());
1121 }
1122
1123 template<typename _Tp, typename _Alloc>
1124 inline shared_ptr<_BoundedArray<_Tp>>
1125 allocate_shared(const _Alloc& __a, const remove_extent_t<_Tp>& __u)
1126 {
1127 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(__a),
1128 std::__addressof(__u));
1129 }
1130
1131 template<typename _Tp>
1132 inline shared_ptr<_BoundedArray<_Tp>>
1133 make_shared(const remove_extent_t<_Tp>& __u)
1134 {
1135 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(),
1136 std::__addressof(__u));
1137 }
1138
1139#if __glibcxx_smart_ptr_for_overwrite
1140 template<typename _Tp, typename _Alloc>
1141 inline shared_ptr<_NotUnboundedArray<_Tp>>
1142 allocate_shared_for_overwrite(const _Alloc& __a)
1143 {
1144 if constexpr (is_array_v<_Tp>)
1145 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(__a),
1146 _Sp_overwrite_tag{});
1147 else
1148 {
1149 // Rebind the allocator to _Sp_overwrite_tag, so that the
1150 // relevant _Sp_counted_ptr_inplace specialization is used.
1151 using _Alloc2 = __alloc_rebind<_Alloc, _Sp_overwrite_tag>;
1152 _Alloc2 __a2 = __a;
1153 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc2>{__a2});
1154 }
1155 }
1156
1157 template<typename _Tp>
1158 inline shared_ptr<_NotUnboundedArray<_Tp>>
1159 make_shared_for_overwrite()
1160 {
1161 if constexpr (is_array_v<_Tp>)
1162 return shared_ptr<_Tp>(std::__make_shared_arrN_tag<_Tp>(),
1163 _Sp_overwrite_tag{});
1164 else
1165 {
1166 using _Alloc = allocator<_Sp_overwrite_tag>;
1167 return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{{}});
1168 }
1169 }
1170
1171 template<typename _Tp, typename _Alloc>
1172 inline shared_ptr<_UnboundedArray<_Tp>>
1173 allocate_shared_for_overwrite(const _Alloc& __a, size_t __n)
1174 {
1175 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n, __a),
1176 _Sp_overwrite_tag{});
1177 }
1178
1179 template<typename _Tp>
1180 inline shared_ptr<_UnboundedArray<_Tp>>
1181 make_shared_for_overwrite(size_t __n)
1182 {
1183 return shared_ptr<_Tp>(std::__make_shared_arr_tag<_Tp>(__n),
1184 _Sp_overwrite_tag{});
1185 }
1186#endif // smart_ptr_for_overwrite
1187#endif // shared_ptr_arrays
1188
1189 /// std::hash specialization for shared_ptr.
1190 template<typename _Tp>
1191 struct hash<shared_ptr<_Tp>>
1192 : public __hash_base<size_t, shared_ptr<_Tp>>
1193 {
1194 size_t
1195 operator()(const shared_ptr<_Tp>& __s) const noexcept
1196 {
1197 return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get());
1198 }
1199 };
1200
1201#if __cpp_variable_templates
1202 template<typename _Tp>
1203 constexpr bool __is_shared_ptr = false;
1204 template<typename _Tp>
1205 constexpr bool __is_shared_ptr<shared_ptr<_Tp>> = true;
1206#endif
1207
1208 /// @} relates shared_ptr
1209 /// @} group pointer_abstractions
1210
1211#if __cplusplus >= 201703L
1212 namespace __detail::__variant
1213 {
1214 template<typename> struct _Never_valueless_alt; // see <variant>
1215
1216 // Provide the strong exception-safety guarantee when emplacing a
1217 // shared_ptr into a variant.
1218 template<typename _Tp>
1219 struct _Never_valueless_alt<std::shared_ptr<_Tp>>
1220 : std::true_type
1221 { };
1222
1223 // Provide the strong exception-safety guarantee when emplacing a
1224 // weak_ptr into a variant.
1225 template<typename _Tp>
1226 struct _Never_valueless_alt<std::weak_ptr<_Tp>>
1227 : std::true_type
1228 { };
1229 } // namespace __detail::__variant
1230#endif // C++17
1231
1232_GLIBCXX_END_NAMESPACE_VERSION
1233} // namespace
1234
1235#endif // _SHARED_PTR_H
shared_ptr_base.h
std::shared_ptr::operator==
bool operator==(const shared_ptr< _Tp > &__a, nullptr_t) noexcept
shared_ptr comparison with nullptr
Definition bits/shared_ptr.h:542
std::shared_ptr::make_shared
shared_ptr< _NonArray< _Tp > > make_shared(_Args &&... __args)
Create an object that is owned by a shared_ptr.
Definition bits/shared_ptr.h:1043
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:681
std::shared_ptr::const_pointer_cast
shared_ptr< _Tp > const_pointer_cast(shared_ptr< _Up > &&__r) noexcept
Convert type of shared_ptr rvalue, via const_cast.
Definition bits/shared_ptr.h:737
std::shared_ptr< _State_base >::get_deleter
_Del * get_deleter(const shared_ptr< _State_base > &__p) noexcept
Definition bits/shared_ptr.h:94
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:536
std::shared_ptr::static_pointer_cast
shared_ptr< _Tp > static_pointer_cast(shared_ptr< _Up > &&__r) noexcept
Convert type of shared_ptr rvalue, via static_cast.
Definition bits/shared_ptr.h:726
std::shared_ptr::reinterpret_pointer_cast
shared_ptr< _Tp > reinterpret_pointer_cast(const shared_ptr< _Up > &__r) noexcept
Convert type of shared_ptr, via reinterpret_cast.
Definition bits/shared_ptr.h:712
std::shared_ptr::allocate_shared
shared_ptr< _NonArray< _Tp > > allocate_shared(const _Alloc &__a, _Args &&... __args)
Create an object that is owned by a shared_ptr.
Definition bits/shared_ptr.h:1028
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:869
std::shared_ptr::reinterpret_pointer_cast
shared_ptr< _Tp > reinterpret_pointer_cast(shared_ptr< _Up > &&__r) noexcept
Convert type of shared_ptr rvalue, via reinterpret_cast.
Definition bits/shared_ptr.h:760
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:699
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:690
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:673
std::shared_ptr::dynamic_pointer_cast
shared_ptr< _Tp > dynamic_pointer_cast(shared_ptr< _Up > &&__r) noexcept
Convert type of shared_ptr rvalue, via dynamic_cast.
Definition bits/shared_ptr.h:748
std::true_type
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
Definition type_traits:119
std::remove_extent_t
typename remove_extent< _Tp >::type remove_extent_t
Alias template for remove_extent.
Definition type_traits:2319
std::remove_all_extents_t
typename remove_all_extents< _Tp >::type remove_all_extents_t
Alias template for remove_all_extents.
Definition type_traits:2323
std::move
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:138
std::__addressof
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition move.h:52
std::forward
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition move.h:72
std
ISO C++ entities toplevel namespace is std.
std::operator<<
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition bitset:1798
std::hash
Primary class template hash.
Definition functional_hash.h:106
std::enable_if
Define a member typedef type only if a boolean constant is true.
Definition type_traits:137
std::is_constructible
is_constructible
Definition type_traits:1265
std::is_assignable
is_assignable
Definition type_traits:1384
std::common_type
common_type
Definition type_traits:2600
std::allocator
The standard allocator, as per C++03 [20.4.1].
Definition allocator.h:134
std::basic_ostream
Template class basic_ostream.
Definition ostream.h:72
std::shared_ptr
A smart pointer with reference-counted copy semantics.
Definition bits/shared_ptr.h:158
std::shared_ptr< _State_base >::element_type
typename __shared_ptr< _State_base >::element_type element_type
Definition bits/shared_ptr.h:172
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:268
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:332
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:349
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:249
std::shared_ptr< _State_base >::shared_ptr
constexpr shared_ptr() noexcept
Definition bits/shared_ptr.h:183
std::shared_ptr::shared_ptr
shared_ptr(const shared_ptr &) noexcept=default
Copy constructor.
std::shared_ptr::shared_ptr
shared_ptr(shared_ptr &&__r) noexcept
Move-constructs a shared_ptr instance from __r.
Definition bits/shared_ptr.h:340
std::shared_ptr::shared_ptr
shared_ptr(_Yp *__p)
Construct a shared_ptr that owns the pointer __p.
Definition bits/shared_ptr.h:195
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:229
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:212
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:292
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:361
std::shared_ptr::shared_ptr
constexpr shared_ptr(nullptr_t) noexcept
Construct an empty shared_ptr.
Definition bits/shared_ptr.h:393
std::shared_ptr::shared_ptr
shared_ptr(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:320
std::weak_ptr
A non-owning observer for a pointer owned by a shared_ptr.
Definition bits/shared_ptr.h:793
std::owner_less
Primary template owner_less.
Definition bits/shared_ptr.h:875
std::auto_ptr
A simple smart pointer providing strict ownership semantics.
Definition auto_ptr.h:94
std::less
One of the comparison functors.
Definition stl_function.h:404
std::unique_ptr
A move-only smart pointer that manages unique ownership of a resource.
Definition unique_ptr.h:271