xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/shared_ptr_base.h (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1 // shared_ptr and weak_ptr implementation details -*- 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 bits/shared_ptr_base.h
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_BASE_H
50 #define _SHARED_PTR_BASE_H 1
51 
52 #include <typeinfo>
53 #include <bits/allocated_ptr.h>
54 #include <bits/allocator.h>
55 #include <bits/exception_defines.h>
56 #include <bits/functional_hash.h>
57 #include <bits/refwrap.h>
58 #include <bits/stl_function.h>  // std::less
59 #include <bits/unique_ptr.h>
60 #include <ext/aligned_buffer.h>
61 #include <ext/atomicity.h>
62 #include <ext/concurrence.h>
63 #if __cplusplus >= 202002L
64 # include <bit>          // __bit_floor
65 # include <compare>
66 # include <bits/align.h> // std::align
67 # include <bits/stl_uninitialized.h>
68 #endif
69 
_GLIBCXX_VISIBILITY(default)70 namespace std _GLIBCXX_VISIBILITY(default)
71 {
72 _GLIBCXX_BEGIN_NAMESPACE_VERSION
73 
74 #if _GLIBCXX_USE_DEPRECATED
75 #pragma GCC diagnostic push
76 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
77   template<typename> class auto_ptr;
78 #pragma GCC diagnostic pop
79 #endif
80 
81  /**
82    *  @brief  Exception possibly thrown by @c shared_ptr.
83    *  @ingroup exceptions
84    */
85   class bad_weak_ptr : public std::exception
86   {
87   public:
88     virtual char const* what() const noexcept;
89 
90     virtual ~bad_weak_ptr() noexcept;
91   };
92 
93   // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
94   inline void
95   __throw_bad_weak_ptr()
96   { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
97 
98   using __gnu_cxx::_Lock_policy;
99   using __gnu_cxx::__default_lock_policy;
100   using __gnu_cxx::_S_single;
101   using __gnu_cxx::_S_mutex;
102   using __gnu_cxx::_S_atomic;
103 
104   // Empty helper class except when the template argument is _S_mutex.
105   template<_Lock_policy _Lp>
106     class _Mutex_base
107     {
108     protected:
109       // The atomic policy uses fully-fenced builtins, single doesn't care.
110       enum { _S_need_barriers = 0 };
111     };
112 
113   template<>
114     class _Mutex_base<_S_mutex>
115     : public __gnu_cxx::__mutex
116     {
117     protected:
118       // This policy is used when atomic builtins are not available.
119       // The replacement atomic operations might not have the necessary
120       // memory barriers.
121       enum { _S_need_barriers = 1 };
122     };
123 
124   template<_Lock_policy _Lp = __default_lock_policy>
125     class _Sp_counted_base
126     : public _Mutex_base<_Lp>
127     {
128     public:
129       _Sp_counted_base() noexcept
130       : _M_use_count(1), _M_weak_count(1) { }
131 
132       virtual
133       ~_Sp_counted_base() noexcept
134       { }
135 
136       // Called when _M_use_count drops to zero, to release the resources
137       // managed by *this.
138       virtual void
139       _M_dispose() noexcept = 0;
140 
141       // Called when _M_weak_count drops to zero.
142       virtual void
143       _M_destroy() noexcept
144       { delete this; }
145 
146       virtual void*
147       _M_get_deleter(const std::type_info&) noexcept = 0;
148 
149       // Increment the use count (used when the count is greater than zero).
150       void
151       _M_add_ref_copy()
152       { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 1); }
153 
154       // Increment the use count if it is non-zero, throw otherwise.
155       void
156       _M_add_ref_lock()
157       {
158 	if (!_M_add_ref_lock_nothrow())
159 	  __throw_bad_weak_ptr();
160       }
161 
162       // Increment the use count if it is non-zero.
163       bool
164       _M_add_ref_lock_nothrow() noexcept;
165 
166       // Decrement the use count.
167       void
168       _M_release() noexcept;
169 
170       // Called by _M_release() when the use count reaches zero.
171       void
172       _M_release_last_use() noexcept
173       {
174 	_GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
175 	_M_dispose();
176 	// There must be a memory barrier between dispose() and destroy()
177 	// to ensure that the effects of dispose() are observed in the
178 	// thread that runs destroy().
179 	// See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
180 	if (_Mutex_base<_Lp>::_S_need_barriers)
181 	  {
182 	    __atomic_thread_fence (__ATOMIC_ACQ_REL);
183 	  }
184 
185 	// Be race-detector-friendly.  For more info see bits/c++config.
186 	_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
187 	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
188 						   -1) == 1)
189 	  {
190 	    _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
191 	    _M_destroy();
192 	  }
193       }
194 
195       // As above, but 'noinline' to reduce code size on the cold path.
196       __attribute__((__noinline__))
197       void
198       _M_release_last_use_cold() noexcept
199       { _M_release_last_use(); }
200 
201       // Increment the weak count.
202       void
203       _M_weak_add_ref() noexcept
204       { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
205 
206       // Decrement the weak count.
207       void
208       _M_weak_release() noexcept
209       {
210         // Be race-detector-friendly. For more info see bits/c++config.
211         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
212 	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
213 	  {
214             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
215 	    if (_Mutex_base<_Lp>::_S_need_barriers)
216 	      {
217 	        // See _M_release(),
218 	        // destroy() must observe results of dispose()
219 		__atomic_thread_fence (__ATOMIC_ACQ_REL);
220 	      }
221 	    _M_destroy();
222 	  }
223       }
224 
225       long
226       _M_get_use_count() const noexcept
227       {
228         // No memory barrier is used here so there is no synchronization
229         // with other threads.
230         return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED);
231       }
232 
233     private:
234       _Sp_counted_base(_Sp_counted_base const&) = delete;
235       _Sp_counted_base& operator=(_Sp_counted_base const&) = delete;
236 
237       _Atomic_word  _M_use_count;     // #shared
238       _Atomic_word  _M_weak_count;    // #weak + (#shared != 0)
239     };
240 
241   template<>
242     inline bool
243     _Sp_counted_base<_S_single>::
244     _M_add_ref_lock_nothrow() noexcept
245     {
246       if (_M_use_count == 0)
247 	return false;
248       ++_M_use_count;
249       return true;
250     }
251 
252   template<>
253     inline bool
254     _Sp_counted_base<_S_mutex>::
255     _M_add_ref_lock_nothrow() noexcept
256     {
257       __gnu_cxx::__scoped_lock sentry(*this);
258       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0)
259 	{
260 	  _M_use_count = 0;
261 	  return false;
262 	}
263       return true;
264     }
265 
266   template<>
267     inline bool
268     _Sp_counted_base<_S_atomic>::
269     _M_add_ref_lock_nothrow() noexcept
270     {
271       // Perform lock-free add-if-not-zero operation.
272       _Atomic_word __count = _M_get_use_count();
273       do
274 	{
275 	  if (__count == 0)
276 	    return false;
277 	  // Replace the current counter value with the old value + 1, as
278 	  // long as it's not changed meanwhile.
279 	}
280       while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
281 					  true, __ATOMIC_ACQ_REL,
282 					  __ATOMIC_RELAXED));
283       return true;
284     }
285 
286   template<>
287     inline void
288     _Sp_counted_base<_S_single>::_M_add_ref_copy()
289     { ++_M_use_count; }
290 
291   template<>
292     inline void
293     _Sp_counted_base<_S_single>::_M_release() noexcept
294     {
295       if (--_M_use_count == 0)
296         {
297           _M_dispose();
298           if (--_M_weak_count == 0)
299             _M_destroy();
300         }
301     }
302 
303   template<>
304     inline void
305     _Sp_counted_base<_S_mutex>::_M_release() noexcept
306     {
307       // Be race-detector-friendly.  For more info see bits/c++config.
308       _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
309       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
310 	{
311 	  _M_release_last_use();
312 	}
313     }
314 
315   template<>
316     inline void
317     _Sp_counted_base<_S_atomic>::_M_release() noexcept
318     {
319       _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
320 #if ! _GLIBCXX_TSAN
321       constexpr bool __lock_free
322 	= __atomic_always_lock_free(sizeof(long long), 0)
323 	&& __atomic_always_lock_free(sizeof(_Atomic_word), 0);
324       constexpr bool __double_word
325 	= sizeof(long long) == 2 * sizeof(_Atomic_word);
326       // The ref-count members follow the vptr, so are aligned to
327       // alignof(void*).
328       constexpr bool __aligned = __alignof(long long) <= alignof(void*);
329       if _GLIBCXX17_CONSTEXPR (__lock_free && __double_word && __aligned)
330 	{
331 	  constexpr int __wordbits = __CHAR_BIT__ * sizeof(_Atomic_word);
332 	  constexpr int __shiftbits = __double_word ? __wordbits : 0;
333 	  constexpr long long __unique_ref = 1LL + (1LL << __shiftbits);
334 	  auto __both_counts = reinterpret_cast<long long*>(&_M_use_count);
335 
336 	  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
337 	  if (__atomic_load_n(__both_counts, __ATOMIC_ACQUIRE) == __unique_ref)
338 	    {
339 	      // Both counts are 1, so there are no weak references and
340 	      // we are releasing the last strong reference. No other
341 	      // threads can observe the effects of this _M_release()
342 	      // call (e.g. calling use_count()) without a data race.
343 	      _M_weak_count = _M_use_count = 0;
344 	      _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
345 	      _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
346 	      _M_dispose();
347 	      _M_destroy();
348 	      return;
349 	    }
350 	  if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
351 	    [[__unlikely__]]
352 	    {
353 	      _M_release_last_use_cold();
354 	      return;
355 	    }
356 	}
357       else
358 #endif
359       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
360 	{
361 	  _M_release_last_use();
362 	}
363     }
364 
365   template<>
366     inline void
367     _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept
368     { ++_M_weak_count; }
369 
370   template<>
371     inline void
372     _Sp_counted_base<_S_single>::_M_weak_release() noexcept
373     {
374       if (--_M_weak_count == 0)
375         _M_destroy();
376     }
377 
378   template<>
379     inline long
380     _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept
381     { return _M_use_count; }
382 
383 
384   // Forward declarations.
385   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
386     class __shared_ptr;
387 
388   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
389     class __weak_ptr;
390 
391   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy>
392     class __enable_shared_from_this;
393 
394   template<typename _Tp>
395     class shared_ptr;
396 
397   template<typename _Tp>
398     class weak_ptr;
399 
400   template<typename _Tp>
401     struct owner_less;
402 
403   template<typename _Tp>
404     class enable_shared_from_this;
405 
406   template<_Lock_policy _Lp = __default_lock_policy>
407     class __weak_count;
408 
409   template<_Lock_policy _Lp = __default_lock_policy>
410     class __shared_count;
411 
412 #if __cplusplus >= 202002L
413   template<typename>
414     class _Sp_atomic;
415 #endif
416 
417   // Counted ptr with no deleter or allocator support
418   template<typename _Ptr, _Lock_policy _Lp>
419     class _Sp_counted_ptr final : public _Sp_counted_base<_Lp>
420     {
421     public:
422       explicit
423       _Sp_counted_ptr(_Ptr __p) noexcept
424       : _M_ptr(__p) { }
425 
426       virtual void
427       _M_dispose() noexcept
428       { delete _M_ptr; }
429 
430       virtual void
431       _M_destroy() noexcept
432       { delete this; }
433 
434       virtual void*
435       _M_get_deleter(const std::type_info&) noexcept
436       { return nullptr; }
437 
438       _Sp_counted_ptr(const _Sp_counted_ptr&) = delete;
439       _Sp_counted_ptr& operator=(const _Sp_counted_ptr&) = delete;
440 
441     private:
442       _Ptr             _M_ptr;
443     };
444 
445   template<>
446     inline void
447     _Sp_counted_ptr<nullptr_t, _S_single>::_M_dispose() noexcept { }
448 
449   template<>
450     inline void
451     _Sp_counted_ptr<nullptr_t, _S_mutex>::_M_dispose() noexcept { }
452 
453   template<>
454     inline void
455     _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { }
456 
457   // FIXME: once __has_cpp_attribute(__no_unique_address__)) is true for
458   // all supported compilers we can greatly simplify _Sp_ebo_helper.
459   // N.B. unconditionally applying the attribute could change layout for
460   // final types, which currently cannot use EBO so have a unique address.
461 
462   template<int _Nm, typename _Tp,
463 	   bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)>
464     struct _Sp_ebo_helper;
465 
466   /// Specialization using EBO.
467   template<int _Nm, typename _Tp>
468     struct _Sp_ebo_helper<_Nm, _Tp, true> : private _Tp
469     {
470       explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { }
471       explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { }
472 
473       static _Tp&
474       _S_get(_Sp_ebo_helper& __eboh) { return static_cast<_Tp&>(__eboh); }
475     };
476 
477   /// Specialization not using EBO.
478   template<int _Nm, typename _Tp>
479     struct _Sp_ebo_helper<_Nm, _Tp, false>
480     {
481       explicit _Sp_ebo_helper(const _Tp& __tp) : _M_tp(__tp) { }
482       explicit _Sp_ebo_helper(_Tp&& __tp) : _M_tp(std::move(__tp)) { }
483 
484       static _Tp&
485       _S_get(_Sp_ebo_helper& __eboh)
486       { return __eboh._M_tp; }
487 
488     private:
489       _Tp _M_tp;
490     };
491 
492   // Support for custom deleter and/or allocator
493   template<typename _Ptr, typename _Deleter, typename _Alloc, _Lock_policy _Lp>
494     class _Sp_counted_deleter final : public _Sp_counted_base<_Lp>
495     {
496       class _Impl : _Sp_ebo_helper<0, _Deleter>, _Sp_ebo_helper<1, _Alloc>
497       {
498 	typedef _Sp_ebo_helper<0, _Deleter>	_Del_base;
499 	typedef _Sp_ebo_helper<1, _Alloc>	_Alloc_base;
500 
501       public:
502 	_Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
503 	: _Del_base(std::move(__d)), _Alloc_base(__a), _M_ptr(__p)
504 	{ }
505 
506 	_Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); }
507 	_Alloc& _M_alloc() noexcept { return _Alloc_base::_S_get(*this); }
508 
509 	_Ptr _M_ptr;
510       };
511 
512     public:
513       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_deleter>;
514 
515       // __d(__p) must not throw.
516       _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
517       : _M_impl(__p, std::move(__d), _Alloc()) { }
518 
519       // __d(__p) must not throw.
520       _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
521       : _M_impl(__p, std::move(__d), __a) { }
522 
523       ~_Sp_counted_deleter() noexcept { }
524 
525       virtual void
526       _M_dispose() noexcept
527       { _M_impl._M_del()(_M_impl._M_ptr); }
528 
529       virtual void
530       _M_destroy() noexcept
531       {
532 	__allocator_type __a(_M_impl._M_alloc());
533 	__allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
534 	this->~_Sp_counted_deleter();
535       }
536 
537       virtual void*
538       _M_get_deleter(const type_info& __ti [[__gnu__::__unused__]]) noexcept
539       {
540 #if __cpp_rtti
541 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
542 	// 2400. shared_ptr's get_deleter() should use addressof()
543         return __ti == typeid(_Deleter)
544 	  ? std::__addressof(_M_impl._M_del())
545 	  : nullptr;
546 #else
547         return nullptr;
548 #endif
549       }
550 
551     private:
552       _Impl _M_impl;
553     };
554 
555   // helpers for make_shared / allocate_shared
556 
557   struct _Sp_make_shared_tag
558   {
559   private:
560     template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
561       friend class _Sp_counted_ptr_inplace;
562 
563     static const type_info&
564     _S_ti() noexcept _GLIBCXX_VISIBILITY(default)
565     {
566       alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { };
567       return reinterpret_cast<const type_info&>(__tag);
568     }
569 
570     static bool _S_eq(const type_info&) noexcept;
571   };
572 
573   template<typename _Alloc>
574     struct _Sp_alloc_shared_tag
575     {
576       const _Alloc& _M_a;
577     };
578 
579   template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
580     class _Sp_counted_ptr_inplace final : public _Sp_counted_base<_Lp>
581     {
582       class _Impl : _Sp_ebo_helper<0, _Alloc>
583       {
584 	typedef _Sp_ebo_helper<0, _Alloc>	_A_base;
585 
586       public:
587 	explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { }
588 
589 	_Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); }
590 
591 	__gnu_cxx::__aligned_buffer<_Tp> _M_storage;
592       };
593 
594     public:
595       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
596 
597       // Alloc parameter is not a reference so doesn't alias anything in __args
598       template<typename... _Args>
599 	_Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
600 	: _M_impl(__a)
601 	{
602 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
603 	  // 2070.  allocate_shared should use allocator_traits<A>::construct
604 	  allocator_traits<_Alloc>::construct(__a, _M_ptr(),
605 	      std::forward<_Args>(__args)...); // might throw
606 	}
607 
608       ~_Sp_counted_ptr_inplace() noexcept { }
609 
610       virtual void
611       _M_dispose() noexcept
612       {
613 	allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
614       }
615 
616       // Override because the allocator needs to know the dynamic type
617       virtual void
618       _M_destroy() noexcept
619       {
620 	__allocator_type __a(_M_impl._M_alloc());
621 	__allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
622 	this->~_Sp_counted_ptr_inplace();
623       }
624 
625     private:
626       friend class __shared_count<_Lp>; // To be able to call _M_ptr().
627 
628       // No longer used, but code compiled against old libstdc++ headers
629       // might still call it from __shared_ptr ctor to get the pointer out.
630       virtual void*
631       _M_get_deleter(const std::type_info& __ti) noexcept override
632       {
633 	auto __ptr = const_cast<typename remove_cv<_Tp>::type*>(_M_ptr());
634 	// Check for the fake type_info first, so we don't try to access it
635 	// as a real type_info object. Otherwise, check if it's the real
636 	// type_info for this class. With RTTI enabled we can check directly,
637 	// or call a library function to do it.
638 	if (&__ti == &_Sp_make_shared_tag::_S_ti()
639 	    ||
640 #if __cpp_rtti
641 	    __ti == typeid(_Sp_make_shared_tag)
642 #else
643 	    _Sp_make_shared_tag::_S_eq(__ti)
644 #endif
645 	   )
646 	  return __ptr;
647 	return nullptr;
648       }
649 
650       _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
651 
652       _Impl _M_impl;
653     };
654 
655 #if __cplusplus >= 202002L
656 # define __cpp_lib_smart_ptr_for_overwrite 202002L
657   struct _Sp_overwrite_tag { };
658 
659   // Partial specialization used for make_shared_for_overwrite<non-array>().
660   // This partial specialization is used when the allocator's value type
661   // is the special _Sp_overwrite_tag type.
662 #if __cpp_concepts
663   template<typename _Tp, typename _Alloc, _Lock_policy _Lp>
664     requires is_same_v<typename _Alloc::value_type, _Sp_overwrite_tag>
665     class _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> final
666 #else
667   template<typename _Tp, template<typename> class _Alloc, _Lock_policy _Lp>
668     class _Sp_counted_ptr_inplace<_Tp, _Alloc<_Sp_overwrite_tag>, _Lp> final
669 #endif
670     : public _Sp_counted_base<_Lp>
671     {
672       [[no_unique_address]] _Alloc _M_alloc;
673 
674       union {
675 	_Tp _M_obj;
676 	char _M_unused;
677       };
678 
679       friend class __shared_count<_Lp>; // To be able to call _M_ptr().
680 
681       _Tp* _M_ptr() noexcept { return std::__addressof(_M_obj); }
682 
683     public:
684       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
685 
686       _Sp_counted_ptr_inplace(const _Alloc& __a)
687       : _M_alloc(__a)
688       {
689 	::new((void*)_M_ptr()) _Tp; // default-initialized, for overwrite.
690       }
691 
692       ~_Sp_counted_ptr_inplace() noexcept { }
693 
694       virtual void
695       _M_dispose() noexcept
696       {
697 	_M_obj.~_Tp();
698       }
699 
700       // Override because the allocator needs to know the dynamic type
701       virtual void
702       _M_destroy() noexcept
703       {
704 	using pointer = typename allocator_traits<__allocator_type>::pointer;
705 	__allocator_type __a(_M_alloc);
706 	auto __p = pointer_traits<pointer>::pointer_to(*this);
707 	__allocated_ptr<__allocator_type> __guard_ptr{ __a, __p };
708 	this->~_Sp_counted_ptr_inplace();
709       }
710 
711       void*
712       _M_get_deleter(const std::type_info&) noexcept override
713       { return nullptr; }
714     };
715 #endif // C++20
716 
717 #if __cplusplus <= 201703L
718 # define __cpp_lib_shared_ptr_arrays 201611L
719 #else
720 # define __cpp_lib_shared_ptr_arrays 201707L
721 
722   struct _Sp_overwrite_tag;
723 
724   // For make_shared<T[]>, make_shared<T[N]>, allocate_shared<T[]> etc.
725   template<typename _Alloc>
726     struct _Sp_counted_array_base
727     {
728       [[no_unique_address]] _Alloc _M_alloc{};
729       size_t _M_n = 0;
730       bool _M_overwrite = false;
731 
732       typename allocator_traits<_Alloc>::pointer
733       _M_alloc_array(size_t __tail)
734       {
735 	return allocator_traits<_Alloc>::allocate(_M_alloc, _M_n + __tail);
736       }
737 
738       void
739       _M_dealloc_array(typename allocator_traits<_Alloc>::pointer __p,
740 		       size_t __tail)
741       {
742 	allocator_traits<_Alloc>::deallocate(_M_alloc, __p, _M_n + __tail);
743       }
744 
745       // Init the array elements
746       template<typename _Init>
747 	void
748 	_M_init(typename allocator_traits<_Alloc>::value_type* __p,
749 		_Init __init)
750 	{
751 	  using _Tp = remove_pointer_t<_Init>;
752 	  using _Up = typename allocator_traits<_Alloc>::value_type;
753 
754 	  if constexpr (is_same_v<_Init, _Sp_overwrite_tag>)
755 	    {
756 	      std::uninitialized_default_construct_n(__p, _M_n);
757 	      _M_overwrite = true;
758 	    }
759 	  else if (__init == nullptr)
760 	    std::__uninitialized_default_n_a(__p, _M_n, _M_alloc);
761 	  else if constexpr (!is_array_v<_Tp>)
762 	    std::__uninitialized_fill_n_a(__p, _M_n, *__init, _M_alloc);
763 	  else
764 	    {
765 #pragma GCC diagnostic push
766 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
767 	      struct _Iter
768 	      {
769 		using value_type = _Up;
770 		using difference_type = ptrdiff_t;
771 		using pointer = const _Up*;
772 		using reference = const _Up&;
773 		using iterator_category = forward_iterator_tag;
774 
775 		const _Up* _M_p;
776 		size_t _M_len;
777 		size_t _M_pos;
778 
779 		_Iter& operator++() { ++_M_pos; return *this; }
780 		_Iter operator++(int) { auto __i(*this); ++_M_pos; return __i; }
781 
782 		reference operator*() const { return _M_p[_M_pos % _M_len]; }
783 		pointer operator->() const { return _M_p + (_M_pos % _M_len); }
784 
785 		bool operator==(const _Iter& __i) const
786 		{ return _M_pos == __i._M_pos; }
787 	      };
788 #pragma GCC diagnostic pop
789 
790 	      _Iter __first{_S_first_elem(__init), sizeof(_Tp) / sizeof(_Up)};
791 	      _Iter __last = __first;
792 	      __last._M_pos = _M_n;
793 	      std::__uninitialized_copy_a(__first, __last, __p, _M_alloc);
794 	    }
795 	}
796 
797     protected:
798       // Destroy the array elements
799       void
800       _M_dispose_array(typename allocator_traits<_Alloc>::value_type* __p)
801       {
802 	if (_M_overwrite)
803 	  std::destroy_n(__p, _M_n);
804 	else
805 	  {
806 	    size_t __n = _M_n;
807 	    while (__n--)
808 	      allocator_traits<_Alloc>::destroy(_M_alloc, __p + __n);
809 	  }
810       }
811 
812     private:
813       template<typename _Tp>
814 	static _Tp*
815 	_S_first_elem(_Tp* __p) { return __p; }
816 
817       template<typename _Tp, size_t _Nm>
818 	static auto
819 	_S_first_elem(_Tp (*__p)[_Nm]) { return _S_first_elem(*__p); }
820     };
821 
822   // Control block for make_shared<T[]>, make_shared<T[N]> etc. that will be
823   // placed into unused memory at the end of the array.
824   template<typename _Alloc, _Lock_policy _Lp>
825     class _Sp_counted_array final
826     : public _Sp_counted_base<_Lp>, _Sp_counted_array_base<_Alloc>
827     {
828       using pointer = typename allocator_traits<_Alloc>::pointer;
829 
830       pointer _M_alloc_ptr;
831 
832       auto _M_ptr() const noexcept { return std::to_address(_M_alloc_ptr); }
833 
834       friend class __shared_count<_Lp>; // To be able to call _M_ptr().
835 
836     public:
837       _Sp_counted_array(const _Sp_counted_array_base<_Alloc>& __a,
838 			pointer __p) noexcept
839       : _Sp_counted_array_base<_Alloc>(__a), _M_alloc_ptr(__p)
840       { }
841 
842       ~_Sp_counted_array() = default;
843 
844       virtual void
845       _M_dispose() noexcept
846       {
847 	if (this->_M_n)
848 	  this->_M_dispose_array(_M_ptr());
849       }
850 
851       // Override because the allocator needs to know the dynamic type
852       virtual void
853       _M_destroy() noexcept
854       {
855 	_Sp_counted_array_base<_Alloc> __a = *this;
856 	pointer __p = _M_alloc_ptr;
857 	this->~_Sp_counted_array();
858 	__a._M_dealloc_array(__p, _S_tail());
859       }
860 
861       // Returns the number of additional array elements that must be
862       // allocated in order to store a _Sp_counted_array at the end.
863       static constexpr size_t
864       _S_tail()
865       {
866 	// The array elemenent type.
867 	using _Tp = typename allocator_traits<_Alloc>::value_type;
868 
869 	// The space needed to store a _Sp_counted_array object.
870 	size_t __bytes = sizeof(_Sp_counted_array);
871 
872 	// Add any padding needed for manual alignment within the buffer.
873 	if constexpr (alignof(_Tp) < alignof(_Sp_counted_array))
874 	  __bytes += alignof(_Sp_counted_array) - alignof(_Tp);
875 
876 	return (__bytes + sizeof(_Tp) - 1) / sizeof(_Tp);
877       }
878 
879       void*
880       _M_get_deleter(const std::type_info&) noexcept override
881       { return nullptr; }
882     };
883 #endif // C++20
884 
885   // The default deleter for shared_ptr<T[]> and shared_ptr<T[N]>.
886   struct __sp_array_delete
887   {
888     template<typename _Yp>
889       void operator()(_Yp* __p) const { delete[] __p; }
890   };
891 
892   template<_Lock_policy _Lp>
893     class __shared_count
894     {
895       // Prevent _Sp_alloc_shared_tag from matching the shared_ptr(P, D) ctor.
896       template<typename _Tp>
897 	struct __not_alloc_shared_tag { using type = void; };
898 
899       template<typename _Tp>
900 	struct __not_alloc_shared_tag<_Sp_alloc_shared_tag<_Tp>> { };
901 
902 #if __cpp_lib_shared_ptr_arrays >= 201707L
903       template<typename _Alloc>
904 	struct __not_alloc_shared_tag<_Sp_counted_array_base<_Alloc>> { };
905 #endif
906 
907     public:
908       constexpr __shared_count() noexcept : _M_pi(0)
909       { }
910 
911       template<typename _Ptr>
912         explicit
913 	__shared_count(_Ptr __p) : _M_pi(0)
914 	{
915 	  __try
916 	    {
917 	      _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
918 	    }
919 	  __catch(...)
920 	    {
921 	      delete __p;
922 	      __throw_exception_again;
923 	    }
924 	}
925 
926       template<typename _Ptr>
927 	__shared_count(_Ptr __p, /* is_array = */ false_type)
928 	: __shared_count(__p)
929 	{ }
930 
931       template<typename _Ptr>
932 	__shared_count(_Ptr __p, /* is_array = */ true_type)
933 	: __shared_count(__p, __sp_array_delete{}, allocator<void>())
934 	{ }
935 
936       template<typename _Ptr, typename _Deleter,
937 	       typename = typename __not_alloc_shared_tag<_Deleter>::type>
938 	__shared_count(_Ptr __p, _Deleter __d)
939 	: __shared_count(__p, std::move(__d), allocator<void>())
940 	{ }
941 
942       template<typename _Ptr, typename _Deleter, typename _Alloc,
943 	       typename = typename __not_alloc_shared_tag<_Deleter>::type>
944 	__shared_count(_Ptr __p, _Deleter __d, _Alloc __a) : _M_pi(0)
945 	{
946 	  typedef _Sp_counted_deleter<_Ptr, _Deleter, _Alloc, _Lp> _Sp_cd_type;
947 	  __try
948 	    {
949 	      typename _Sp_cd_type::__allocator_type __a2(__a);
950 	      auto __guard = std::__allocate_guarded(__a2);
951 	      _Sp_cd_type* __mem = __guard.get();
952 	      ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a));
953 	      _M_pi = __mem;
954 	      __guard = nullptr;
955 	    }
956 	  __catch(...)
957 	    {
958 	      __d(__p); // Call _Deleter on __p.
959 	      __throw_exception_again;
960 	    }
961 	}
962 
963       template<typename _Tp, typename _Alloc, typename... _Args>
964 	__shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a,
965 		       _Args&&... __args)
966 	{
967 	  typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
968 	  typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
969 	  auto __guard = std::__allocate_guarded(__a2);
970 	  _Sp_cp_type* __mem = __guard.get();
971 	  auto __pi = ::new (__mem)
972 	    _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
973 	  __guard = nullptr;
974 	  _M_pi = __pi;
975 	  __p = __pi->_M_ptr();
976 	}
977 
978 #if __cpp_lib_shared_ptr_arrays >= 201707L
979       template<typename _Tp, typename _Alloc, typename _Init>
980 	__shared_count(_Tp*& __p, const _Sp_counted_array_base<_Alloc>& __a,
981 		       _Init __init)
982 	{
983 	  using _Up = remove_all_extents_t<_Tp>;
984 	  static_assert(is_same_v<_Up, typename _Alloc::value_type>);
985 
986 	  using _Sp_ca_type = _Sp_counted_array<_Alloc, _Lp>;
987 	  const size_t __tail = _Sp_ca_type::_S_tail();
988 
989 	  struct _Guarded_ptr : _Sp_counted_array_base<_Alloc>
990 	  {
991 	    typename allocator_traits<_Alloc>::pointer _M_ptr;
992 
993 	    _Guarded_ptr(_Sp_counted_array_base<_Alloc> __a)
994 	    : _Sp_counted_array_base<_Alloc>(__a),
995 	      _M_ptr(this->_M_alloc_array(_Sp_ca_type::_S_tail()))
996 	    { }
997 
998 	    ~_Guarded_ptr()
999 	    {
1000 	      if (_M_ptr)
1001 		this->_M_dealloc_array(_M_ptr, _Sp_ca_type::_S_tail());
1002 	    }
1003 	  };
1004 
1005 	  _Guarded_ptr __guard{__a};
1006 	  _Up* const __raw = std::to_address(__guard._M_ptr);
1007 	  __guard._M_init(__raw, __init); // might throw
1008 
1009 	  void* __c = __raw + __a._M_n;
1010 	  if constexpr (alignof(_Up) < alignof(_Sp_ca_type))
1011 	    {
1012 	      size_t __space = sizeof(_Up) * __tail;
1013 	      __c = std::align(alignof(_Sp_ca_type), sizeof(_Sp_ca_type),
1014 			       __c, __space);
1015 	    }
1016 	  auto __pi = ::new(__c) _Sp_ca_type(__guard, __guard._M_ptr);
1017 	  __guard._M_ptr = nullptr;
1018 	  _M_pi = __pi;
1019 	  __p = reinterpret_cast<_Tp*>(__raw);
1020 	}
1021 #endif
1022 
1023 #if _GLIBCXX_USE_DEPRECATED
1024 #pragma GCC diagnostic push
1025 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1026       // Special case for auto_ptr<_Tp> to provide the strong guarantee.
1027       template<typename _Tp>
1028         explicit
1029 	__shared_count(std::auto_ptr<_Tp>&& __r);
1030 #pragma GCC diagnostic pop
1031 #endif
1032 
1033       // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
1034       template<typename _Tp, typename _Del>
1035         explicit
1036 	__shared_count(std::unique_ptr<_Tp, _Del>&& __r) : _M_pi(0)
1037 	{
1038 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1039 	  // 2415. Inconsistency between unique_ptr and shared_ptr
1040 	  if (__r.get() == nullptr)
1041 	    return;
1042 
1043 	  using _Ptr = typename unique_ptr<_Tp, _Del>::pointer;
1044 	  using _Del2 = __conditional_t<is_reference<_Del>::value,
1045 	      reference_wrapper<typename remove_reference<_Del>::type>,
1046 	      _Del>;
1047 	  using _Sp_cd_type
1048 	    = _Sp_counted_deleter<_Ptr, _Del2, allocator<void>, _Lp>;
1049 	  using _Alloc = allocator<_Sp_cd_type>;
1050 	  using _Alloc_traits = allocator_traits<_Alloc>;
1051 	  _Alloc __a;
1052 	  _Sp_cd_type* __mem = _Alloc_traits::allocate(__a, 1);
1053 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1054 	  // 3548. shared_ptr construction from unique_ptr should move
1055 	  // (not copy) the deleter
1056 	  _Alloc_traits::construct(__a, __mem, __r.release(),
1057 				   std::forward<_Del>(__r.get_deleter()));
1058 	  _M_pi = __mem;
1059 	}
1060 
1061       // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
1062       explicit __shared_count(const __weak_count<_Lp>& __r);
1063 
1064       // Does not throw if __r._M_get_use_count() == 0, caller must check.
1065       explicit
1066       __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept;
1067 
1068       ~__shared_count() noexcept
1069       {
1070 	if (_M_pi != nullptr)
1071 	  _M_pi->_M_release();
1072       }
1073 
1074       __shared_count(const __shared_count& __r) noexcept
1075       : _M_pi(__r._M_pi)
1076       {
1077 	if (_M_pi != nullptr)
1078 	  _M_pi->_M_add_ref_copy();
1079       }
1080 
1081       __shared_count&
1082       operator=(const __shared_count& __r) noexcept
1083       {
1084 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
1085 	if (__tmp != _M_pi)
1086 	  {
1087 	    if (__tmp != nullptr)
1088 	      __tmp->_M_add_ref_copy();
1089 	    if (_M_pi != nullptr)
1090 	      _M_pi->_M_release();
1091 	    _M_pi = __tmp;
1092 	  }
1093 	return *this;
1094       }
1095 
1096       void
1097       _M_swap(__shared_count& __r) noexcept
1098       {
1099 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
1100 	__r._M_pi = _M_pi;
1101 	_M_pi = __tmp;
1102       }
1103 
1104       long
1105       _M_get_use_count() const noexcept
1106       { return _M_pi ? _M_pi->_M_get_use_count() : 0; }
1107 
1108       bool
1109       _M_unique() const noexcept
1110       { return this->_M_get_use_count() == 1; }
1111 
1112       void*
1113       _M_get_deleter(const std::type_info& __ti) const noexcept
1114       { return _M_pi ? _M_pi->_M_get_deleter(__ti) : nullptr; }
1115 
1116       bool
1117       _M_less(const __shared_count& __rhs) const noexcept
1118       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
1119 
1120       bool
1121       _M_less(const __weak_count<_Lp>& __rhs) const noexcept
1122       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
1123 
1124       // Friend function injected into enclosing namespace and found by ADL
1125       friend inline bool
1126       operator==(const __shared_count& __a, const __shared_count& __b) noexcept
1127       { return __a._M_pi == __b._M_pi; }
1128 
1129     private:
1130       friend class __weak_count<_Lp>;
1131 #if __cplusplus >= 202002L
1132       template<typename> friend class _Sp_atomic;
1133 #endif
1134 
1135       _Sp_counted_base<_Lp>*  _M_pi;
1136     };
1137 
1138 
1139   template<_Lock_policy _Lp>
1140     class __weak_count
1141     {
1142     public:
1143       constexpr __weak_count() noexcept : _M_pi(nullptr)
1144       { }
1145 
1146       __weak_count(const __shared_count<_Lp>& __r) noexcept
1147       : _M_pi(__r._M_pi)
1148       {
1149 	if (_M_pi != nullptr)
1150 	  _M_pi->_M_weak_add_ref();
1151       }
1152 
1153       __weak_count(const __weak_count& __r) noexcept
1154       : _M_pi(__r._M_pi)
1155       {
1156 	if (_M_pi != nullptr)
1157 	  _M_pi->_M_weak_add_ref();
1158       }
1159 
1160       __weak_count(__weak_count&& __r) noexcept
1161       : _M_pi(__r._M_pi)
1162       { __r._M_pi = nullptr; }
1163 
1164       ~__weak_count() noexcept
1165       {
1166 	if (_M_pi != nullptr)
1167 	  _M_pi->_M_weak_release();
1168       }
1169 
1170       __weak_count&
1171       operator=(const __shared_count<_Lp>& __r) noexcept
1172       {
1173 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
1174 	if (__tmp != nullptr)
1175 	  __tmp->_M_weak_add_ref();
1176 	if (_M_pi != nullptr)
1177 	  _M_pi->_M_weak_release();
1178 	_M_pi = __tmp;
1179 	return *this;
1180       }
1181 
1182       __weak_count&
1183       operator=(const __weak_count& __r) noexcept
1184       {
1185 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
1186 	if (__tmp != nullptr)
1187 	  __tmp->_M_weak_add_ref();
1188 	if (_M_pi != nullptr)
1189 	  _M_pi->_M_weak_release();
1190 	_M_pi = __tmp;
1191 	return *this;
1192       }
1193 
1194       __weak_count&
1195       operator=(__weak_count&& __r) noexcept
1196       {
1197 	if (_M_pi != nullptr)
1198 	  _M_pi->_M_weak_release();
1199 	_M_pi = __r._M_pi;
1200         __r._M_pi = nullptr;
1201 	return *this;
1202       }
1203 
1204       void
1205       _M_swap(__weak_count& __r) noexcept
1206       {
1207 	_Sp_counted_base<_Lp>* __tmp = __r._M_pi;
1208 	__r._M_pi = _M_pi;
1209 	_M_pi = __tmp;
1210       }
1211 
1212       long
1213       _M_get_use_count() const noexcept
1214       { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
1215 
1216       bool
1217       _M_less(const __weak_count& __rhs) const noexcept
1218       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
1219 
1220       bool
1221       _M_less(const __shared_count<_Lp>& __rhs) const noexcept
1222       { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); }
1223 
1224       // Friend function injected into enclosing namespace and found by ADL
1225       friend inline bool
1226       operator==(const __weak_count& __a, const __weak_count& __b) noexcept
1227       { return __a._M_pi == __b._M_pi; }
1228 
1229     private:
1230       friend class __shared_count<_Lp>;
1231 #if __cplusplus >= 202002L
1232       template<typename> friend class _Sp_atomic;
1233 #endif
1234 
1235       _Sp_counted_base<_Lp>*  _M_pi;
1236     };
1237 
1238   // Now that __weak_count is defined we can define this constructor:
1239   template<_Lock_policy _Lp>
1240     inline
1241     __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
1242     : _M_pi(__r._M_pi)
1243     {
1244       if (_M_pi == nullptr || !_M_pi->_M_add_ref_lock_nothrow())
1245 	__throw_bad_weak_ptr();
1246     }
1247 
1248   // Now that __weak_count is defined we can define this constructor:
1249   template<_Lock_policy _Lp>
1250     inline
1251     __shared_count<_Lp>::
1252     __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept
1253     : _M_pi(__r._M_pi)
1254     {
1255       if (_M_pi && !_M_pi->_M_add_ref_lock_nothrow())
1256 	_M_pi = nullptr;
1257     }
1258 
1259   // Helper traits for shared_ptr of array:
1260 
1261   // A pointer type Y* is said to be compatible with a pointer type T* when
1262   // either Y* is convertible to T* or Y is U[N] and T is U cv [].
1263   template<typename _Yp_ptr, typename _Tp_ptr>
1264     struct __sp_compatible_with
1265     : false_type
1266     { };
1267 
1268   template<typename _Yp, typename _Tp>
1269     struct __sp_compatible_with<_Yp*, _Tp*>
1270     : is_convertible<_Yp*, _Tp*>::type
1271     { };
1272 
1273   template<typename _Up, size_t _Nm>
1274     struct __sp_compatible_with<_Up(*)[_Nm], _Up(*)[]>
1275     : true_type
1276     { };
1277 
1278   template<typename _Up, size_t _Nm>
1279     struct __sp_compatible_with<_Up(*)[_Nm], const _Up(*)[]>
1280     : true_type
1281     { };
1282 
1283   template<typename _Up, size_t _Nm>
1284     struct __sp_compatible_with<_Up(*)[_Nm], volatile _Up(*)[]>
1285     : true_type
1286     { };
1287 
1288   template<typename _Up, size_t _Nm>
1289     struct __sp_compatible_with<_Up(*)[_Nm], const volatile _Up(*)[]>
1290     : true_type
1291     { };
1292 
1293   // Test conversion from Y(*)[N] to U(*)[N] without forming invalid type Y[N].
1294   template<typename _Up, size_t _Nm, typename _Yp, typename = void>
1295     struct __sp_is_constructible_arrN
1296     : false_type
1297     { };
1298 
1299   template<typename _Up, size_t _Nm, typename _Yp>
1300     struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
1301     : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
1302     { };
1303 
1304   // Test conversion from Y(*)[] to U(*)[] without forming invalid type Y[].
1305   template<typename _Up, typename _Yp, typename = void>
1306     struct __sp_is_constructible_arr
1307     : false_type
1308     { };
1309 
1310   template<typename _Up, typename _Yp>
1311     struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
1312     : is_convertible<_Yp(*)[], _Up(*)[]>::type
1313     { };
1314 
1315   // Trait to check if shared_ptr<T> can be constructed from Y*.
1316   template<typename _Tp, typename _Yp>
1317     struct __sp_is_constructible;
1318 
1319   // When T is U[N], Y(*)[N] shall be convertible to T*;
1320   template<typename _Up, size_t _Nm, typename _Yp>
1321     struct __sp_is_constructible<_Up[_Nm], _Yp>
1322     : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
1323     { };
1324 
1325   // when T is U[], Y(*)[] shall be convertible to T*;
1326   template<typename _Up, typename _Yp>
1327     struct __sp_is_constructible<_Up[], _Yp>
1328     : __sp_is_constructible_arr<_Up, _Yp>::type
1329     { };
1330 
1331   // otherwise, Y* shall be convertible to T*.
1332   template<typename _Tp, typename _Yp>
1333     struct __sp_is_constructible
1334     : is_convertible<_Yp*, _Tp*>::type
1335     { };
1336 
1337 
1338   // Define operator* and operator-> for shared_ptr<T>.
1339   template<typename _Tp, _Lock_policy _Lp,
1340 	   bool = is_array<_Tp>::value, bool = is_void<_Tp>::value>
1341     class __shared_ptr_access
1342     {
1343     public:
1344       using element_type = _Tp;
1345 
1346       element_type&
1347       operator*() const noexcept
1348       {
1349 	__glibcxx_assert(_M_get() != nullptr);
1350 	return *_M_get();
1351       }
1352 
1353       element_type*
1354       operator->() const noexcept
1355       {
1356 	_GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
1357 	return _M_get();
1358       }
1359 
1360     private:
1361       element_type*
1362       _M_get() const noexcept
1363       { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
1364     };
1365 
1366   // Define operator-> for shared_ptr<cv void>.
1367   template<typename _Tp, _Lock_policy _Lp>
1368     class __shared_ptr_access<_Tp, _Lp, false, true>
1369     {
1370     public:
1371       using element_type = _Tp;
1372 
1373       element_type*
1374       operator->() const noexcept
1375       {
1376 	auto __ptr = static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get();
1377 	_GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr);
1378 	return __ptr;
1379       }
1380     };
1381 
1382   // Define operator[] for shared_ptr<T[]> and shared_ptr<T[N]>.
1383   template<typename _Tp, _Lock_policy _Lp>
1384     class __shared_ptr_access<_Tp, _Lp, true, false>
1385     {
1386     public:
1387       using element_type = typename remove_extent<_Tp>::type;
1388 
1389 #if __cplusplus <= 201402L
1390       [[__deprecated__("shared_ptr<T[]>::operator* is absent from C++17")]]
1391       element_type&
1392       operator*() const noexcept
1393       {
1394 	__glibcxx_assert(_M_get() != nullptr);
1395 	return *_M_get();
1396       }
1397 
1398       [[__deprecated__("shared_ptr<T[]>::operator-> is absent from C++17")]]
1399       element_type*
1400       operator->() const noexcept
1401       {
1402 	_GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
1403 	return _M_get();
1404       }
1405 #endif
1406 
1407       element_type&
1408       operator[](ptrdiff_t __i) const noexcept
1409       {
1410 	__glibcxx_assert(_M_get() != nullptr);
1411 	__glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value);
1412 	return _M_get()[__i];
1413       }
1414 
1415     private:
1416       element_type*
1417       _M_get() const noexcept
1418       { return static_cast<const __shared_ptr<_Tp, _Lp>*>(this)->get(); }
1419     };
1420 
1421   template<typename _Tp, _Lock_policy _Lp>
1422     class __shared_ptr
1423     : public __shared_ptr_access<_Tp, _Lp>
1424     {
1425     public:
1426       using element_type = typename remove_extent<_Tp>::type;
1427 
1428     private:
1429       // Constraint for taking ownership of a pointer of type _Yp*:
1430       template<typename _Yp>
1431 	using _SafeConv
1432 	  = typename enable_if<__sp_is_constructible<_Tp, _Yp>::value>::type;
1433 
1434       // Constraint for construction from shared_ptr and weak_ptr:
1435       template<typename _Yp, typename _Res = void>
1436 	using _Compatible = typename
1437 	  enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
1438 
1439       // Constraint for assignment from shared_ptr and weak_ptr:
1440       template<typename _Yp>
1441 	using _Assignable = _Compatible<_Yp, __shared_ptr&>;
1442 
1443       // Constraint for construction from unique_ptr:
1444       template<typename _Yp, typename _Del, typename _Res = void,
1445 	       typename _Ptr = typename unique_ptr<_Yp, _Del>::pointer>
1446 	using _UniqCompatible = __enable_if_t<__and_<
1447 	  __sp_compatible_with<_Yp*, _Tp*>,
1448 	  is_convertible<_Ptr, element_type*>,
1449 	  is_move_constructible<_Del>
1450 	  >::value, _Res>;
1451 
1452       // Constraint for assignment from unique_ptr:
1453       template<typename _Yp, typename _Del>
1454 	using _UniqAssignable = _UniqCompatible<_Yp, _Del, __shared_ptr&>;
1455 
1456     public:
1457 
1458 #if __cplusplus > 201402L
1459       using weak_type = __weak_ptr<_Tp, _Lp>;
1460 #endif
1461 
1462       constexpr __shared_ptr() noexcept
1463       : _M_ptr(0), _M_refcount()
1464       { }
1465 
1466       template<typename _Yp, typename = _SafeConv<_Yp>>
1467 	explicit
1468 	__shared_ptr(_Yp* __p)
1469 	: _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type())
1470 	{
1471 	  static_assert( !is_void<_Yp>::value, "incomplete type" );
1472 	  static_assert( sizeof(_Yp) > 0, "incomplete type" );
1473 	  _M_enable_shared_from_this_with(__p);
1474 	}
1475 
1476       template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>>
1477 	__shared_ptr(_Yp* __p, _Deleter __d)
1478 	: _M_ptr(__p), _M_refcount(__p, std::move(__d))
1479 	{
1480 	  static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1481 	      "deleter expression d(p) is well-formed");
1482 	  _M_enable_shared_from_this_with(__p);
1483 	}
1484 
1485       template<typename _Yp, typename _Deleter, typename _Alloc,
1486 	       typename = _SafeConv<_Yp>>
1487 	__shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
1488 	: _M_ptr(__p), _M_refcount(__p, std::move(__d), std::move(__a))
1489 	{
1490 	  static_assert(__is_invocable<_Deleter&, _Yp*&>::value,
1491 	      "deleter expression d(p) is well-formed");
1492 	  _M_enable_shared_from_this_with(__p);
1493 	}
1494 
1495       template<typename _Deleter>
1496 	__shared_ptr(nullptr_t __p, _Deleter __d)
1497 	: _M_ptr(0), _M_refcount(__p, std::move(__d))
1498 	{ }
1499 
1500       template<typename _Deleter, typename _Alloc>
1501         __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
1502 	: _M_ptr(0), _M_refcount(__p, std::move(__d), std::move(__a))
1503 	{ }
1504 
1505       // Aliasing constructor
1506       template<typename _Yp>
1507 	__shared_ptr(const __shared_ptr<_Yp, _Lp>& __r,
1508 		     element_type* __p) noexcept
1509 	: _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
1510 	{ }
1511 
1512       // Aliasing constructor
1513       template<typename _Yp>
1514 	__shared_ptr(__shared_ptr<_Yp, _Lp>&& __r,
1515 		     element_type* __p) noexcept
1516 	: _M_ptr(__p), _M_refcount()
1517 	{
1518 	  _M_refcount._M_swap(__r._M_refcount);
1519 	  __r._M_ptr = nullptr;
1520 	}
1521 
1522       __shared_ptr(const __shared_ptr&) noexcept = default;
1523       __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
1524       ~__shared_ptr() = default;
1525 
1526       template<typename _Yp, typename = _Compatible<_Yp>>
1527 	__shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1528 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1529 	{ }
1530 
1531       __shared_ptr(__shared_ptr&& __r) noexcept
1532       : _M_ptr(__r._M_ptr), _M_refcount()
1533       {
1534 	_M_refcount._M_swap(__r._M_refcount);
1535 	__r._M_ptr = nullptr;
1536       }
1537 
1538       template<typename _Yp, typename = _Compatible<_Yp>>
1539 	__shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1540 	: _M_ptr(__r._M_ptr), _M_refcount()
1541 	{
1542 	  _M_refcount._M_swap(__r._M_refcount);
1543 	  __r._M_ptr = nullptr;
1544 	}
1545 
1546       template<typename _Yp, typename = _Compatible<_Yp>>
1547 	explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r)
1548 	: _M_refcount(__r._M_refcount) // may throw
1549 	{
1550 	  // It is now safe to copy __r._M_ptr, as
1551 	  // _M_refcount(__r._M_refcount) did not throw.
1552 	  _M_ptr = __r._M_ptr;
1553 	}
1554 
1555       // If an exception is thrown this constructor has no effect.
1556       template<typename _Yp, typename _Del,
1557 	       typename = _UniqCompatible<_Yp, _Del>>
1558 	__shared_ptr(unique_ptr<_Yp, _Del>&& __r)
1559 	: _M_ptr(__r.get()), _M_refcount()
1560 	{
1561 	  auto __raw = __to_address(__r.get());
1562 	  _M_refcount = __shared_count<_Lp>(std::move(__r));
1563 	  _M_enable_shared_from_this_with(__raw);
1564 	}
1565 
1566 #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
1567     protected:
1568       // If an exception is thrown this constructor has no effect.
1569       template<typename _Tp1, typename _Del,
1570 	       typename enable_if<__and_<
1571 		 __not_<is_array<_Tp>>, is_array<_Tp1>,
1572 	         is_convertible<typename unique_ptr<_Tp1, _Del>::pointer, _Tp*>
1573 	       >::value, bool>::type = true>
1574 	__shared_ptr(unique_ptr<_Tp1, _Del>&& __r, __sp_array_delete)
1575 	: _M_ptr(__r.get()), _M_refcount()
1576 	{
1577 	  auto __raw = __to_address(__r.get());
1578 	  _M_refcount = __shared_count<_Lp>(std::move(__r));
1579 	  _M_enable_shared_from_this_with(__raw);
1580 	}
1581     public:
1582 #endif
1583 
1584 #if _GLIBCXX_USE_DEPRECATED
1585 #pragma GCC diagnostic push
1586 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1587       // Postcondition: use_count() == 1 and __r.get() == 0
1588       template<typename _Yp, typename = _Compatible<_Yp>>
1589 	__shared_ptr(auto_ptr<_Yp>&& __r);
1590 #pragma GCC diagnostic pop
1591 #endif
1592 
1593       constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
1594 
1595       template<typename _Yp>
1596 	_Assignable<_Yp>
1597 	operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1598 	{
1599 	  _M_ptr = __r._M_ptr;
1600 	  _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
1601 	  return *this;
1602 	}
1603 
1604 #if _GLIBCXX_USE_DEPRECATED
1605 #pragma GCC diagnostic push
1606 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1607       template<typename _Yp>
1608 	_Assignable<_Yp>
1609 	operator=(auto_ptr<_Yp>&& __r)
1610 	{
1611 	  __shared_ptr(std::move(__r)).swap(*this);
1612 	  return *this;
1613 	}
1614 #pragma GCC diagnostic pop
1615 #endif
1616 
1617       __shared_ptr&
1618       operator=(__shared_ptr&& __r) noexcept
1619       {
1620 	__shared_ptr(std::move(__r)).swap(*this);
1621 	return *this;
1622       }
1623 
1624       template<class _Yp>
1625 	_Assignable<_Yp>
1626 	operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1627 	{
1628 	  __shared_ptr(std::move(__r)).swap(*this);
1629 	  return *this;
1630 	}
1631 
1632       template<typename _Yp, typename _Del>
1633 	_UniqAssignable<_Yp, _Del>
1634 	operator=(unique_ptr<_Yp, _Del>&& __r)
1635 	{
1636 	  __shared_ptr(std::move(__r)).swap(*this);
1637 	  return *this;
1638 	}
1639 
1640       void
1641       reset() noexcept
1642       { __shared_ptr().swap(*this); }
1643 
1644       template<typename _Yp>
1645 	_SafeConv<_Yp>
1646 	reset(_Yp* __p) // _Yp must be complete.
1647 	{
1648 	  // Catch self-reset errors.
1649 	  __glibcxx_assert(__p == nullptr || __p != _M_ptr);
1650 	  __shared_ptr(__p).swap(*this);
1651 	}
1652 
1653       template<typename _Yp, typename _Deleter>
1654 	_SafeConv<_Yp>
1655 	reset(_Yp* __p, _Deleter __d)
1656 	{ __shared_ptr(__p, std::move(__d)).swap(*this); }
1657 
1658       template<typename _Yp, typename _Deleter, typename _Alloc>
1659 	_SafeConv<_Yp>
1660 	reset(_Yp* __p, _Deleter __d, _Alloc __a)
1661         { __shared_ptr(__p, std::move(__d), std::move(__a)).swap(*this); }
1662 
1663       /// Return the stored pointer.
1664       element_type*
1665       get() const noexcept
1666       { return _M_ptr; }
1667 
1668       /// Return true if the stored pointer is not null.
1669 #if __cplusplus >= 202002L
1670       [[__gnu__::__always_inline__]]
1671 #endif
1672       explicit operator bool() const noexcept
1673       { return _M_ptr != nullptr; }
1674 
1675       /// Return true if use_count() == 1.
1676       bool
1677       unique() const noexcept
1678       { return _M_refcount._M_unique(); }
1679 
1680       /// If *this owns a pointer, return the number of owners, otherwise zero.
1681       long
1682       use_count() const noexcept
1683       { return _M_refcount._M_get_use_count(); }
1684 
1685       /// Exchange both the owned pointer and the stored pointer.
1686       void
1687       swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
1688       {
1689 	std::swap(_M_ptr, __other._M_ptr);
1690 	_M_refcount._M_swap(__other._M_refcount);
1691       }
1692 
1693       /** @brief Define an ordering based on ownership.
1694        *
1695        * This function defines a strict weak ordering between two shared_ptr
1696        * or weak_ptr objects, such that one object is less than the other
1697        * unless they share ownership of the same pointer, or are both empty.
1698        * @{
1699       */
1700       template<typename _Tp1>
1701 	bool
1702 	owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1703 	{ return _M_refcount._M_less(__rhs._M_refcount); }
1704 
1705       template<typename _Tp1>
1706 	bool
1707 	owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1708 	{ return _M_refcount._M_less(__rhs._M_refcount); }
1709       /// @}
1710 
1711     protected:
1712       // This constructor is non-standard, it is used by allocate_shared.
1713       template<typename _Alloc, typename... _Args>
1714 	__shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
1715 	: _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
1716 	{ _M_enable_shared_from_this_with(_M_ptr); }
1717 
1718       template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
1719 	       typename... _Args>
1720 	friend __shared_ptr<_Tp1, _Lp1>
1721 	__allocate_shared(const _Alloc& __a, _Args&&... __args);
1722 
1723 #if __cpp_lib_shared_ptr_arrays >= 201707L
1724       // This constructor is non-standard, it is used by allocate_shared<T[]>.
1725       template<typename _Alloc, typename _Init = const remove_extent_t<_Tp>*>
1726 	__shared_ptr(const _Sp_counted_array_base<_Alloc>& __a,
1727 		     _Init __init = nullptr)
1728 	: _M_ptr(), _M_refcount(_M_ptr, __a, __init)
1729 	{ }
1730 #endif
1731 
1732       // This constructor is used by __weak_ptr::lock() and
1733       // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
1734       __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) noexcept
1735       : _M_refcount(__r._M_refcount, std::nothrow)
1736       {
1737 	_M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr;
1738       }
1739 
1740       friend class __weak_ptr<_Tp, _Lp>;
1741 
1742     private:
1743 
1744       template<typename _Yp>
1745 	using __esft_base_t = decltype(__enable_shared_from_this_base(
1746 	      std::declval<const __shared_count<_Lp>&>(),
1747 	      std::declval<_Yp*>()));
1748 
1749       // Detect an accessible and unambiguous enable_shared_from_this base.
1750       template<typename _Yp, typename = void>
1751 	struct __has_esft_base
1752 	: false_type { };
1753 
1754       template<typename _Yp>
1755 	struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
1756 	: __not_<is_array<_Tp>> { }; // No enable shared_from_this for arrays
1757 
1758       template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1759 	typename enable_if<__has_esft_base<_Yp2>::value>::type
1760 	_M_enable_shared_from_this_with(_Yp* __p) noexcept
1761 	{
1762 	  if (auto __base = __enable_shared_from_this_base(_M_refcount, __p))
1763 	    __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount);
1764 	}
1765 
1766       template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1767 	typename enable_if<!__has_esft_base<_Yp2>::value>::type
1768 	_M_enable_shared_from_this_with(_Yp*) noexcept
1769 	{ }
1770 
1771       void*
1772       _M_get_deleter(const std::type_info& __ti) const noexcept
1773       { return _M_refcount._M_get_deleter(__ti); }
1774 
1775       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
1776       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
1777 
1778       template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
1779 	friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
1780 
1781       template<typename _Del, typename _Tp1>
1782 	friend _Del* get_deleter(const shared_ptr<_Tp1>&) noexcept;
1783 
1784 #if __cplusplus >= 202002L
1785       friend _Sp_atomic<shared_ptr<_Tp>>;
1786 #endif
1787 
1788       element_type*	   _M_ptr;         // Contained pointer.
1789       __shared_count<_Lp>  _M_refcount;    // Reference counter.
1790     };
1791 
1792 
1793   // 20.7.2.2.7 shared_ptr comparisons
1794   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1795     inline bool
1796     operator==(const __shared_ptr<_Tp1, _Lp>& __a,
1797 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1798     { return __a.get() == __b.get(); }
1799 
1800   template<typename _Tp, _Lock_policy _Lp>
1801     inline bool
1802     operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1803     { return !__a; }
1804 
1805 #ifdef __cpp_lib_three_way_comparison
1806   template<typename _Tp, typename _Up, _Lock_policy _Lp>
1807     inline strong_ordering
1808     operator<=>(const __shared_ptr<_Tp, _Lp>& __a,
1809 		const __shared_ptr<_Up, _Lp>& __b) noexcept
1810     { return compare_three_way()(__a.get(), __b.get()); }
1811 
1812   template<typename _Tp, _Lock_policy _Lp>
1813     inline strong_ordering
1814     operator<=>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1815     {
1816       using pointer = typename __shared_ptr<_Tp, _Lp>::element_type*;
1817       return compare_three_way()(__a.get(), static_cast<pointer>(nullptr));
1818     }
1819 #else
1820   template<typename _Tp, _Lock_policy _Lp>
1821     inline bool
1822     operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1823     { return !__a; }
1824 
1825   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1826     inline bool
1827     operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
1828 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1829     { return __a.get() != __b.get(); }
1830 
1831   template<typename _Tp, _Lock_policy _Lp>
1832     inline bool
1833     operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1834     { return (bool)__a; }
1835 
1836   template<typename _Tp, _Lock_policy _Lp>
1837     inline bool
1838     operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1839     { return (bool)__a; }
1840 
1841   template<typename _Tp, typename _Up, _Lock_policy _Lp>
1842     inline bool
1843     operator<(const __shared_ptr<_Tp, _Lp>& __a,
1844 	      const __shared_ptr<_Up, _Lp>& __b) noexcept
1845     {
1846       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1847       using _Up_elt = typename __shared_ptr<_Up, _Lp>::element_type;
1848       using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
1849       return less<_Vp>()(__a.get(), __b.get());
1850     }
1851 
1852   template<typename _Tp, _Lock_policy _Lp>
1853     inline bool
1854     operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1855     {
1856       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1857       return less<_Tp_elt*>()(__a.get(), nullptr);
1858     }
1859 
1860   template<typename _Tp, _Lock_policy _Lp>
1861     inline bool
1862     operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1863     {
1864       using _Tp_elt = typename __shared_ptr<_Tp, _Lp>::element_type;
1865       return less<_Tp_elt*>()(nullptr, __a.get());
1866     }
1867 
1868   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1869     inline bool
1870     operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
1871 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1872     { return !(__b < __a); }
1873 
1874   template<typename _Tp, _Lock_policy _Lp>
1875     inline bool
1876     operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1877     { return !(nullptr < __a); }
1878 
1879   template<typename _Tp, _Lock_policy _Lp>
1880     inline bool
1881     operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1882     { return !(__a < nullptr); }
1883 
1884   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1885     inline bool
1886     operator>(const __shared_ptr<_Tp1, _Lp>& __a,
1887 	      const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1888     { return (__b < __a); }
1889 
1890   template<typename _Tp, _Lock_policy _Lp>
1891     inline bool
1892     operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1893     { return nullptr < __a; }
1894 
1895   template<typename _Tp, _Lock_policy _Lp>
1896     inline bool
1897     operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1898     { return __a < nullptr; }
1899 
1900   template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
1901     inline bool
1902     operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
1903 	       const __shared_ptr<_Tp2, _Lp>& __b) noexcept
1904     { return !(__a < __b); }
1905 
1906   template<typename _Tp, _Lock_policy _Lp>
1907     inline bool
1908     operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
1909     { return !(__a < nullptr); }
1910 
1911   template<typename _Tp, _Lock_policy _Lp>
1912     inline bool
1913     operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
1914     { return !(nullptr < __a); }
1915 #endif // three-way comparison
1916 
1917   // 20.7.2.2.8 shared_ptr specialized algorithms.
1918   template<typename _Tp, _Lock_policy _Lp>
1919     inline void
1920     swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
1921     { __a.swap(__b); }
1922 
1923   // 20.7.2.2.9 shared_ptr casts
1924 
1925   // The seemingly equivalent code:
1926   // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
1927   // will eventually result in undefined behaviour, attempting to
1928   // delete the same object twice.
1929   /// static_pointer_cast
1930   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1931     inline __shared_ptr<_Tp, _Lp>
1932     static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1933     {
1934       using _Sp = __shared_ptr<_Tp, _Lp>;
1935       return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
1936     }
1937 
1938   // The seemingly equivalent code:
1939   // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
1940   // will eventually result in undefined behaviour, attempting to
1941   // delete the same object twice.
1942   /// const_pointer_cast
1943   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1944     inline __shared_ptr<_Tp, _Lp>
1945     const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1946     {
1947       using _Sp = __shared_ptr<_Tp, _Lp>;
1948       return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
1949     }
1950 
1951   // The seemingly equivalent code:
1952   // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
1953   // will eventually result in undefined behaviour, attempting to
1954   // delete the same object twice.
1955   /// dynamic_pointer_cast
1956   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1957     inline __shared_ptr<_Tp, _Lp>
1958     dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1959     {
1960       using _Sp = __shared_ptr<_Tp, _Lp>;
1961       if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
1962 	return _Sp(__r, __p);
1963       return _Sp();
1964     }
1965 
1966 #if __cplusplus > 201402L
1967   template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
1968     inline __shared_ptr<_Tp, _Lp>
1969     reinterpret_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
1970     {
1971       using _Sp = __shared_ptr<_Tp, _Lp>;
1972       return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
1973     }
1974 #endif
1975 
1976   template<typename _Tp, _Lock_policy _Lp>
1977     class __weak_ptr
1978     {
1979       template<typename _Yp, typename _Res = void>
1980 	using _Compatible = typename
1981 	  enable_if<__sp_compatible_with<_Yp*, _Tp*>::value, _Res>::type;
1982 
1983       // Constraint for assignment from shared_ptr and weak_ptr:
1984       template<typename _Yp>
1985 	using _Assignable = _Compatible<_Yp, __weak_ptr&>;
1986 
1987     public:
1988       using element_type = typename remove_extent<_Tp>::type;
1989 
1990       constexpr __weak_ptr() noexcept
1991       : _M_ptr(nullptr), _M_refcount()
1992       { }
1993 
1994       __weak_ptr(const __weak_ptr&) noexcept = default;
1995 
1996       ~__weak_ptr() = default;
1997 
1998       // The "obvious" converting constructor implementation:
1999       //
2000       //  template<typename _Tp1>
2001       //    __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
2002       //    : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
2003       //    { }
2004       //
2005       // has a serious problem.
2006       //
2007       //  __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
2008       //  conversion may require access to *__r._M_ptr (virtual inheritance).
2009       //
2010       // It is not possible to avoid spurious access violations since
2011       // in multithreaded programs __r._M_ptr may be invalidated at any point.
2012       template<typename _Yp, typename = _Compatible<_Yp>>
2013 	__weak_ptr(const __weak_ptr<_Yp, _Lp>& __r) noexcept
2014 	: _M_refcount(__r._M_refcount)
2015         { _M_ptr = __r.lock().get(); }
2016 
2017       template<typename _Yp, typename = _Compatible<_Yp>>
2018 	__weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
2019 	: _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
2020 	{ }
2021 
2022       __weak_ptr(__weak_ptr&& __r) noexcept
2023       : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
2024       { __r._M_ptr = nullptr; }
2025 
2026       template<typename _Yp, typename = _Compatible<_Yp>>
2027 	__weak_ptr(__weak_ptr<_Yp, _Lp>&& __r) noexcept
2028 	: _M_ptr(__r.lock().get()), _M_refcount(std::move(__r._M_refcount))
2029         { __r._M_ptr = nullptr; }
2030 
2031       __weak_ptr&
2032       operator=(const __weak_ptr& __r) noexcept = default;
2033 
2034       template<typename _Yp>
2035 	_Assignable<_Yp>
2036 	operator=(const __weak_ptr<_Yp, _Lp>& __r) noexcept
2037 	{
2038 	  _M_ptr = __r.lock().get();
2039 	  _M_refcount = __r._M_refcount;
2040 	  return *this;
2041 	}
2042 
2043       template<typename _Yp>
2044 	_Assignable<_Yp>
2045 	operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
2046 	{
2047 	  _M_ptr = __r._M_ptr;
2048 	  _M_refcount = __r._M_refcount;
2049 	  return *this;
2050 	}
2051 
2052       __weak_ptr&
2053       operator=(__weak_ptr&& __r) noexcept
2054       {
2055 	__weak_ptr(std::move(__r)).swap(*this);
2056 	return *this;
2057       }
2058 
2059       template<typename _Yp>
2060 	_Assignable<_Yp>
2061 	operator=(__weak_ptr<_Yp, _Lp>&& __r) noexcept
2062 	{
2063 	  _M_ptr = __r.lock().get();
2064 	  _M_refcount = std::move(__r._M_refcount);
2065 	  __r._M_ptr = nullptr;
2066 	  return *this;
2067 	}
2068 
2069       __shared_ptr<_Tp, _Lp>
2070       lock() const noexcept
2071       { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); }
2072 
2073       long
2074       use_count() const noexcept
2075       { return _M_refcount._M_get_use_count(); }
2076 
2077       bool
2078       expired() const noexcept
2079       { return _M_refcount._M_get_use_count() == 0; }
2080 
2081       template<typename _Tp1>
2082 	bool
2083 	owner_before(const __shared_ptr<_Tp1, _Lp>& __rhs) const noexcept
2084 	{ return _M_refcount._M_less(__rhs._M_refcount); }
2085 
2086       template<typename _Tp1>
2087 	bool
2088 	owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept
2089 	{ return _M_refcount._M_less(__rhs._M_refcount); }
2090 
2091       void
2092       reset() noexcept
2093       { __weak_ptr().swap(*this); }
2094 
2095       void
2096       swap(__weak_ptr& __s) noexcept
2097       {
2098 	std::swap(_M_ptr, __s._M_ptr);
2099 	_M_refcount._M_swap(__s._M_refcount);
2100       }
2101 
2102     private:
2103       // Used by __enable_shared_from_this.
2104       void
2105       _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
2106       {
2107 	if (use_count() == 0)
2108 	  {
2109 	    _M_ptr = __ptr;
2110 	    _M_refcount = __refcount;
2111 	  }
2112       }
2113 
2114       template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
2115       template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
2116       friend class __enable_shared_from_this<_Tp, _Lp>;
2117       friend class enable_shared_from_this<_Tp>;
2118 #if __cplusplus >= 202002L
2119       friend _Sp_atomic<weak_ptr<_Tp>>;
2120 #endif
2121 
2122       element_type*	 _M_ptr;         // Contained pointer.
2123       __weak_count<_Lp>  _M_refcount;    // Reference counter.
2124     };
2125 
2126   // 20.7.2.3.6 weak_ptr specialized algorithms.
2127   template<typename _Tp, _Lock_policy _Lp>
2128     inline void
2129     swap(__weak_ptr<_Tp, _Lp>& __a, __weak_ptr<_Tp, _Lp>& __b) noexcept
2130     { __a.swap(__b); }
2131 
2132 #pragma GCC diagnostic push
2133 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
2134   template<typename _Tp, typename _Tp1>
2135     struct _Sp_owner_less : public binary_function<_Tp, _Tp, bool>
2136     {
2137       bool
2138       operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept
2139       { return __lhs.owner_before(__rhs); }
2140 
2141       bool
2142       operator()(const _Tp& __lhs, const _Tp1& __rhs) const noexcept
2143       { return __lhs.owner_before(__rhs); }
2144 
2145       bool
2146       operator()(const _Tp1& __lhs, const _Tp& __rhs) const noexcept
2147       { return __lhs.owner_before(__rhs); }
2148     };
2149 #pragma GCC diagnostic pop
2150 
2151   template<>
2152     struct _Sp_owner_less<void, void>
2153     {
2154       template<typename _Tp, typename _Up>
2155 	auto
2156 	operator()(const _Tp& __lhs, const _Up& __rhs) const noexcept
2157 	-> decltype(__lhs.owner_before(__rhs))
2158 	{ return __lhs.owner_before(__rhs); }
2159 
2160       using is_transparent = void;
2161     };
2162 
2163   template<typename _Tp, _Lock_policy _Lp>
2164     struct owner_less<__shared_ptr<_Tp, _Lp>>
2165     : public _Sp_owner_less<__shared_ptr<_Tp, _Lp>, __weak_ptr<_Tp, _Lp>>
2166     { };
2167 
2168   template<typename _Tp, _Lock_policy _Lp>
2169     struct owner_less<__weak_ptr<_Tp, _Lp>>
2170     : public _Sp_owner_less<__weak_ptr<_Tp, _Lp>, __shared_ptr<_Tp, _Lp>>
2171     { };
2172 
2173 
2174   template<typename _Tp, _Lock_policy _Lp>
2175     class __enable_shared_from_this
2176     {
2177     protected:
2178       constexpr __enable_shared_from_this() noexcept { }
2179 
2180       __enable_shared_from_this(const __enable_shared_from_this&) noexcept { }
2181 
2182       __enable_shared_from_this&
2183       operator=(const __enable_shared_from_this&) noexcept
2184       { return *this; }
2185 
2186       ~__enable_shared_from_this() { }
2187 
2188     public:
2189       __shared_ptr<_Tp, _Lp>
2190       shared_from_this()
2191       { return __shared_ptr<_Tp, _Lp>(this->_M_weak_this); }
2192 
2193       __shared_ptr<const _Tp, _Lp>
2194       shared_from_this() const
2195       { return __shared_ptr<const _Tp, _Lp>(this->_M_weak_this); }
2196 
2197 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
2198       __weak_ptr<_Tp, _Lp>
2199       weak_from_this() noexcept
2200       { return this->_M_weak_this; }
2201 
2202       __weak_ptr<const _Tp, _Lp>
2203       weak_from_this() const noexcept
2204       { return this->_M_weak_this; }
2205 #endif
2206 
2207     private:
2208       template<typename _Tp1>
2209 	void
2210 	_M_weak_assign(_Tp1* __p, const __shared_count<_Lp>& __n) const noexcept
2211 	{ _M_weak_this._M_assign(__p, __n); }
2212 
2213       friend const __enable_shared_from_this*
2214       __enable_shared_from_this_base(const __shared_count<_Lp>&,
2215 				     const __enable_shared_from_this* __p)
2216       { return __p; }
2217 
2218       template<typename, _Lock_policy>
2219 	friend class __shared_ptr;
2220 
2221       mutable __weak_ptr<_Tp, _Lp>  _M_weak_this;
2222     };
2223 
2224   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
2225 	   typename _Alloc, typename... _Args>
2226     inline __shared_ptr<_Tp, _Lp>
2227     __allocate_shared(const _Alloc& __a, _Args&&... __args)
2228     {
2229       static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported");
2230 
2231       return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a},
2232 				    std::forward<_Args>(__args)...);
2233     }
2234 
2235   template<typename _Tp, _Lock_policy _Lp = __default_lock_policy,
2236 	   typename... _Args>
2237     inline __shared_ptr<_Tp, _Lp>
2238     __make_shared(_Args&&... __args)
2239     {
2240       typedef typename std::remove_const<_Tp>::type _Tp_nc;
2241       return std::__allocate_shared<_Tp, _Lp>(std::allocator<_Tp_nc>(),
2242 					      std::forward<_Args>(__args)...);
2243     }
2244 
2245   /// std::hash specialization for __shared_ptr.
2246   template<typename _Tp, _Lock_policy _Lp>
2247     struct hash<__shared_ptr<_Tp, _Lp>>
2248     : public __hash_base<size_t, __shared_ptr<_Tp, _Lp>>
2249     {
2250       size_t
2251       operator()(const __shared_ptr<_Tp, _Lp>& __s) const noexcept
2252       {
2253 	return hash<typename __shared_ptr<_Tp, _Lp>::element_type*>()(
2254 	    __s.get());
2255       }
2256     };
2257 
2258 _GLIBCXX_END_NAMESPACE_VERSION
2259 } // namespace
2260 
2261 #endif // _SHARED_PTR_BASE_H
2262