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