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