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