Line data Source code
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 :
67 : namespace 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 0 : __throw_bad_weak_ptr()
93 0 : { _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 149060 : _Sp_counted_base() noexcept
127 149060 : : _M_use_count(1), _M_weak_count(1) { }
128 :
129 : virtual
130 1192585 : ~_Sp_counted_base() noexcept
131 1192585 : { }
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 0 : _M_destroy() noexcept
141 0 : { delete this; }
142 :
143 : virtual void*
144 : _M_get_deleter(const std::type_info&) noexcept = 0;
145 :
146 : void
147 9105967 : _M_add_ref_copy()
148 9105967 : { __gnu_cxx::__atomic_add_dispatch(&_M_use_count, 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 26129332 : _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 52258664 : if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
166 : {
167 : _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
168 3883172 : _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 3883136 : if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
181 3883136 : -1) == 1)
182 : {
183 : _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
184 2962951 : _M_destroy();
185 : }
186 : }
187 26129368 : }
188 :
189 : void
190 5528062 : _M_weak_add_ref() noexcept
191 5528062 : { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count, 1); }
192 :
193 : void
194 5562638 : _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 11125276 : if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -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 8047 : _M_destroy();
208 : }
209 5562638 : }
210 :
211 : long
212 350063 : _M_get_use_count() const noexcept
213 : {
214 : // No memory barrier is used here so there is no synchronization
215 : // with other threads.
216 350063 : 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(&_M_use_count, 1) == 0)
245 : {
246 : _M_use_count = 0;
247 : return false;
248 : }
249 : return true;
250 : }
251 :
252 : template<>
253 : inline bool
254 214782 : _Sp_counted_base<_S_atomic>::
255 : _M_add_ref_lock_nothrow() noexcept
256 : {
257 : // Perform lock-free add-if-not-zero operation.
258 214782 : _Atomic_word __count = _M_get_use_count();
259 : do
260 : {
261 214968 : if (__count == 0)
262 2310 : return false;
263 : // Replace the current counter value with the old value + 1, as
264 : // long as it's not changed meanwhile.
265 : }
266 212658 : while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1,
267 : true, __ATOMIC_ACQ_REL,
268 : __ATOMIC_RELAXED));
269 212464 : 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 25657 : _Sp_counted_ptr(_Ptr __p) noexcept
344 25657 : : _M_ptr(__p) { }
345 :
346 : virtual void
347 25656 : _M_dispose() noexcept
348 25656 : { delete _M_ptr; }
349 :
350 : virtual void
351 25656 : _M_destroy() noexcept
352 25656 : { delete this; }
353 :
354 : virtual void*
355 0 : _M_get_deleter(const std::type_info&) noexcept
356 0 : { 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 123409 : explicit _Sp_ebo_helper(const _Tp& __tp) : _Tp(__tp) { }
386 1211 : explicit _Sp_ebo_helper(_Tp&& __tp) : _Tp(std::move(__tp)) { }
387 :
388 : static _Tp&
389 2333907 : _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 1211 : _Impl(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
418 1211 : : _Del_base(std::move(__d)), _Alloc_base(__a), _M_ptr(__p)
419 1211 : { }
420 :
421 1210 : _Deleter& _M_del() noexcept { return _Del_base::_S_get(*this); }
422 1209 : _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 1211 : _Sp_counted_deleter(_Ptr __p, _Deleter __d) noexcept
432 1211 : : _M_impl(__p, std::move(__d), _Alloc()) { }
433 :
434 : // __d(__p) must not throw.
435 0 : _Sp_counted_deleter(_Ptr __p, _Deleter __d, const _Alloc& __a) noexcept
436 0 : : _M_impl(__p, std::move(__d), __a) { }
437 :
438 1209 : ~_Sp_counted_deleter() noexcept { }
439 :
440 : virtual void
441 1210 : _M_dispose() noexcept
442 1210 : { _M_impl._M_del()(_M_impl._M_ptr); }
443 :
444 : virtual void
445 1209 : _M_destroy() noexcept
446 : {
447 1209 : __allocator_type __a(_M_impl._M_alloc());
448 1209 : __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
449 1209 : this->~_Sp_counted_deleter();
450 1209 : }
451 :
452 : virtual void*
453 0 : _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 0 : return __ti == typeid(_Deleter)
459 0 : ? std::__addressof(_M_impl._M_del())
460 0 : : 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 0 : _S_ti() noexcept _GLIBCXX_VISIBILITY(default)
480 : {
481 : alignas(type_info) static constexpr char __tag[sizeof(type_info)] = { };
482 0 : 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 122198 : explicit _Impl(_Alloc __a) noexcept : _A_base(__a) { }
503 :
504 2331488 : _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 122198 : _Sp_counted_ptr_inplace(_Alloc __a, _Args&&... __args)
515 122198 : : _M_impl(__a)
516 : {
517 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
518 : // 2070. allocate_shared should use allocator_traits<A>::construct
519 122198 : allocator_traits<_Alloc>::construct(__a, _M_ptr(),
520 : std::forward<_Args>(__args)...); // might throw
521 122199 : }
522 :
523 1165736 : ~_Sp_counted_ptr_inplace() noexcept { }
524 :
525 : virtual void
526 1165752 : _M_dispose() noexcept
527 : {
528 1165752 : allocator_traits<_Alloc>::destroy(_M_impl._M_alloc(), _M_ptr());
529 1165752 : }
530 :
531 : // Override because the allocator needs to know the dynamic type
532 : virtual void
533 1165736 : _M_destroy() noexcept
534 : {
535 1165736 : __allocator_type __a(_M_impl._M_alloc());
536 1165736 : __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
537 1165736 : this->~_Sp_counted_ptr_inplace();
538 1165736 : }
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 0 : _M_get_deleter(const std::type_info& __ti) noexcept override
547 : {
548 0 : 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 0 : if (&__ti == &_Sp_make_shared_tag::_S_ti()
554 0 : ||
555 : #if __cpp_rtti
556 0 : __ti == typeid(_Sp_make_shared_tag)
557 : #else
558 : _Sp_make_shared_tag::_S_eq(__ti)
559 : #endif
560 : )
561 0 : return __ptr;
562 0 : return nullptr;
563 : }
564 :
565 1410147 : _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 553397 : constexpr __shared_count() noexcept : _M_pi(0)
588 553397 : { }
589 :
590 : template<typename _Ptr>
591 : explicit
592 25657 : __shared_count(_Ptr __p) : _M_pi(0)
593 : {
594 : __try
595 : {
596 25657 : _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p);
597 : }
598 0 : __catch(...)
599 : {
600 0 : delete __p;
601 0 : __throw_exception_again;
602 : }
603 25657 : }
604 :
605 : template<typename _Ptr>
606 25657 : __shared_count(_Ptr __p, /* is_array = */ false_type)
607 25657 : : __shared_count(__p)
608 25657 : { }
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 0 : __shared_count(_Ptr __p, _Deleter __d)
618 0 : : __shared_count(__p, std::move(__d), allocator<void>())
619 0 : { }
620 :
621 : template<typename _Ptr, typename _Deleter, typename _Alloc,
622 : typename = typename __not_alloc_shared_tag<_Deleter>::type>
623 0 : __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 0 : typename _Sp_cd_type::__allocator_type __a2(__a);
629 0 : auto __guard = std::__allocate_guarded(__a2);
630 0 : _Sp_cd_type* __mem = __guard.get();
631 0 : ::new (__mem) _Sp_cd_type(__p, std::move(__d), std::move(__a));
632 0 : _M_pi = __mem;
633 0 : __guard = nullptr;
634 0 : }
635 0 : __catch(...)
636 : {
637 0 : __d(__p); // Call _Deleter on __p.
638 0 : __throw_exception_again;
639 : }
640 0 : }
641 :
642 : template<typename _Tp, typename _Alloc, typename... _Args>
643 122198 : __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 122198 : typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
648 122198 : auto __guard = std::__allocate_guarded(__a2);
649 122198 : _Sp_cp_type* __mem = __guard.get();
650 185033 : auto __pi = ::new (__mem)
651 62833 : _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
652 122197 : __guard = nullptr;
653 122197 : _M_pi = __pi;
654 122197 : __p = __pi->_M_ptr();
655 122199 : }
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 1211 : __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 1211 : if (__r.get() == nullptr)
675 0 : 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 1211 : _Alloc __a;
686 1211 : _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 1211 : _Alloc_traits::construct(__a, __mem, __r.release(),
691 1211 : std::forward<_Del>(__r.get_deleter()));
692 1211 : _M_pi = __mem;
693 1211 : }
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 2874667 : ~__shared_count() noexcept
703 : {
704 2874667 : if (_M_pi != nullptr)
705 1706313 : _M_pi->_M_release();
706 2874786 : }
707 :
708 9021988 : __shared_count(const __shared_count& __r) noexcept
709 9021988 : : _M_pi(__r._M_pi)
710 : {
711 9021988 : if (_M_pi != nullptr)
712 9003246 : _M_pi->_M_add_ref_copy();
713 9022078 : }
714 :
715 : __shared_count&
716 106261 : operator=(const __shared_count& __r) noexcept
717 : {
718 106261 : _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
719 106261 : if (__tmp != _M_pi)
720 : {
721 103656 : if (__tmp != nullptr)
722 103312 : __tmp->_M_add_ref_copy();
723 103657 : if (_M_pi != nullptr)
724 18437 : _M_pi->_M_release();
725 103657 : _M_pi = __tmp;
726 : }
727 106262 : return *this;
728 : }
729 :
730 : void
731 430390 : _M_swap(__shared_count& __r) noexcept
732 : {
733 430390 : _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
734 430390 : __r._M_pi = _M_pi;
735 430390 : _M_pi = __tmp;
736 430390 : }
737 :
738 : long
739 136936 : _M_get_use_count() const noexcept
740 136936 : { return _M_pi ? _M_pi->_M_get_use_count() : 0; }
741 :
742 : bool
743 3030 : _M_unique() const noexcept
744 3030 : { 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 32776 : _M_less(const __shared_count& __rhs) const noexcept
752 32776 : { 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 11334 : constexpr __weak_count() noexcept : _M_pi(nullptr)
775 11334 : { }
776 :
777 90080 : __weak_count(const __shared_count<_Lp>& __r) noexcept
778 90080 : : _M_pi(__r._M_pi)
779 : {
780 90080 : if (_M_pi != nullptr)
781 90080 : _M_pi->_M_weak_add_ref();
782 90080 : }
783 :
784 5427275 : __weak_count(const __weak_count& __r) noexcept
785 5427275 : : _M_pi(__r._M_pi)
786 : {
787 5427275 : if (_M_pi != nullptr)
788 5427259 : _M_pi->_M_weak_add_ref();
789 5427277 : }
790 :
791 145190 : __weak_count(__weak_count&& __r) noexcept
792 145190 : : _M_pi(__r._M_pi)
793 145190 : { __r._M_pi = nullptr; }
794 :
795 346778 : ~__weak_count() noexcept
796 : {
797 346778 : if (_M_pi != nullptr)
798 199328 : _M_pi->_M_weak_release();
799 346781 : }
800 :
801 : __weak_count&
802 10725 : operator=(const __shared_count<_Lp>& __r) noexcept
803 : {
804 10725 : _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
805 10725 : if (__tmp != nullptr)
806 10725 : __tmp->_M_weak_add_ref();
807 10725 : if (_M_pi != nullptr)
808 269 : _M_pi->_M_weak_release();
809 10725 : _M_pi = __tmp;
810 10725 : 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 71 : _M_swap(__weak_count& __r) noexcept
837 : {
838 71 : _Sp_counted_base<_Lp>* __tmp = __r._M_pi;
839 71 : __r._M_pi = _M_pi;
840 71 : _M_pi = __tmp;
841 71 : }
842 :
843 : long
844 9539 : _M_get_use_count() const noexcept
845 9539 : { return _M_pi != nullptr ? _M_pi->_M_get_use_count() : 0; }
846 :
847 : bool
848 1794 : _M_less(const __weak_count& __rhs) const noexcept
849 1794 : { 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 81806 : __shared_count<_Lp>::__shared_count(const __weak_count<_Lp>& __r)
870 81806 : : _M_pi(__r._M_pi)
871 : {
872 81806 : if (_M_pi == nullptr || !_M_pi->_M_add_ref_lock_nothrow())
873 0 : __throw_bad_weak_ptr();
874 81806 : }
875 :
876 : // Now that __weak_count is defined we can define this constructor:
877 : template<_Lock_policy _Lp>
878 : inline
879 133920 : __shared_count<_Lp>::
880 : __shared_count(const __weak_count<_Lp>& __r, std::nothrow_t) noexcept
881 133920 : : _M_pi(__r._M_pi)
882 : {
883 133920 : if (_M_pi && !_M_pi->_M_add_ref_lock_nothrow())
884 2310 : _M_pi = nullptr;
885 133924 : }
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 369217 : operator*() const noexcept
978 : {
979 369217 : __glibcxx_assert(_M_get() != nullptr);
980 369217 : return *_M_get();
981 : }
982 :
983 : element_type*
984 186085809 : operator->() const noexcept
985 : {
986 : _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr);
987 186085809 : return _M_get();
988 : }
989 :
990 : private:
991 : element_type*
992 186455010 : _M_get() const noexcept
993 186455010 : { 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 251283 : constexpr __shared_ptr() noexcept
1093 251283 : : _M_ptr(0), _M_refcount()
1094 251283 : { }
1095 :
1096 : template<typename _Yp, typename = _SafeConv<_Yp>>
1097 : explicit
1098 25657 : __shared_ptr(_Yp* __p)
1099 25657 : : _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 25657 : _M_enable_shared_from_this_with(__p);
1104 25657 : }
1105 :
1106 : template<typename _Yp, typename _Deleter, typename = _SafeConv<_Yp>>
1107 0 : __shared_ptr(_Yp* __p, _Deleter __d)
1108 0 : : _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 0 : _M_enable_shared_from_this_with(__p);
1113 0 : }
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 143228 : __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r,
1138 : element_type* __p) noexcept
1139 143228 : : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
1140 143222 : { }
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 889780 : __shared_ptr(const __shared_ptr&) noexcept = default;
1153 44529 : __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
1154 2874637 : ~__shared_ptr() = default;
1155 :
1156 : template<typename _Yp, typename = _Compatible<_Yp>>
1157 3080 : __shared_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1158 3080 : : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1159 3080 : { }
1160 :
1161 279888 : __shared_ptr(__shared_ptr&& __r) noexcept
1162 279888 : : _M_ptr(__r._M_ptr), _M_refcount()
1163 : {
1164 279888 : _M_refcount._M_swap(__r._M_refcount);
1165 279888 : __r._M_ptr = nullptr;
1166 279888 : }
1167 :
1168 : template<typename _Yp, typename = _Compatible<_Yp>>
1169 21047 : __shared_ptr(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1170 21047 : : _M_ptr(__r._M_ptr), _M_refcount()
1171 : {
1172 21047 : _M_refcount._M_swap(__r._M_refcount);
1173 21047 : __r._M_ptr = nullptr;
1174 21047 : }
1175 :
1176 : template<typename _Yp, typename = _Compatible<_Yp>>
1177 81111 : explicit __shared_ptr(const __weak_ptr<_Yp, _Lp>& __r)
1178 81111 : : _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 81111 : _M_ptr = __r._M_ptr;
1183 81111 : }
1184 :
1185 : // If an exception is thrown this constructor has no effect.
1186 : template<typename _Yp, typename _Del,
1187 : typename = _UniqCompatible<_Yp, _Del>>
1188 1211 : __shared_ptr(unique_ptr<_Yp, _Del>&& __r)
1189 1211 : : _M_ptr(__r.get()), _M_refcount()
1190 : {
1191 1211 : auto __raw = __to_address(__r.get());
1192 1211 : _M_refcount = __shared_count<_Lp>(std::move(__r));
1193 1211 : _M_enable_shared_from_this_with(__raw);
1194 1211 : }
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 28 : operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1228 : {
1229 28 : _M_ptr = __r._M_ptr;
1230 28 : _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
1231 28 : 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 116347 : operator=(__shared_ptr&& __r) noexcept
1249 : {
1250 116347 : __shared_ptr(std::move(__r)).swap(*this);
1251 116347 : return *this;
1252 : }
1253 :
1254 : template<class _Yp>
1255 : _Assignable<_Yp>
1256 1359 : operator=(__shared_ptr<_Yp, _Lp>&& __r) noexcept
1257 : {
1258 1359 : __shared_ptr(std::move(__r)).swap(*this);
1259 1359 : return *this;
1260 : }
1261 :
1262 : template<typename _Yp, typename _Del>
1263 : _UniqAssignable<_Yp, _Del>
1264 0 : operator=(unique_ptr<_Yp, _Del>&& __r)
1265 : {
1266 0 : __shared_ptr(std::move(__r)).swap(*this);
1267 0 : return *this;
1268 : }
1269 :
1270 : void
1271 3979 : reset() noexcept
1272 3979 : { __shared_ptr().swap(*this); }
1273 :
1274 : template<typename _Yp>
1275 : _SafeConv<_Yp>
1276 5897 : reset(_Yp* __p) // _Yp must be complete.
1277 : {
1278 : // Catch self-reset errors.
1279 : __glibcxx_assert(__p == nullptr || __p != _M_ptr);
1280 5897 : __shared_ptr(__p).swap(*this);
1281 5897 : }
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 186662700 : get() const noexcept
1296 186662700 : { return _M_ptr; }
1297 :
1298 : /// Return true if the stored pointer is not null.
1299 92714110 : explicit operator bool() const noexcept
1300 92714110 : { return _M_ptr != nullptr; }
1301 :
1302 : /// Return true if use_count() == 1.
1303 : bool
1304 3030 : unique() const noexcept
1305 3030 : { 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 129475 : swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
1315 : {
1316 129475 : std::swap(_M_ptr, __other._M_ptr);
1317 129475 : _M_refcount._M_swap(__other._M_refcount);
1318 129475 : }
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 32776 : owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept
1330 32776 : { 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 122198 : __shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
1342 122198 : : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
1343 122197 : { _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 133927 : __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) noexcept
1353 133927 : : _M_refcount(__r._M_refcount, std::nothrow)
1354 : {
1355 133928 : _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr;
1356 133921 : }
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 7897 : _M_enable_shared_from_this_with(_Yp* __p) noexcept
1379 : {
1380 7897 : if (auto __base = __enable_shared_from_this_base(_M_refcount, __p))
1381 7897 : __base->_M_weak_assign(const_cast<_Yp2*>(__p), _M_refcount);
1382 7897 : }
1383 :
1384 : template<typename _Yp, typename _Yp2 = typename remove_cv<_Yp>::type>
1385 : typename enable_if<!__has_esft_base<_Yp2>::value>::type
1386 141168 : _M_enable_shared_from_this_with(_Yp*) noexcept
1387 141168 : { }
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 11334 : constexpr __weak_ptr() noexcept
1605 11334 : : _M_ptr(nullptr), _M_refcount()
1606 11334 : { }
1607 :
1608 108216 : __weak_ptr(const __weak_ptr&) noexcept = default;
1609 :
1610 346785 : ~__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 80674 : __weak_ptr(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1633 80674 : : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
1634 80674 : { }
1635 :
1636 145194 : __weak_ptr(__weak_ptr&& __r) noexcept
1637 145194 : : _M_ptr(__r._M_ptr), _M_refcount(std::move(__r._M_refcount))
1638 145190 : { __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 2828 : operator=(const __shared_ptr<_Yp, _Lp>& __r) noexcept
1660 : {
1661 2828 : _M_ptr = __r._M_ptr;
1662 2828 : _M_refcount = __r._M_refcount;
1663 2828 : return *this;
1664 : }
1665 :
1666 : __weak_ptr&
1667 0 : operator=(__weak_ptr&& __r) noexcept
1668 : {
1669 0 : __weak_ptr(std::move(__r)).swap(*this);
1670 0 : 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 7897 : use_count() const noexcept
1689 7897 : { return _M_refcount._M_get_use_count(); }
1690 :
1691 : bool
1692 1642 : expired() const noexcept
1693 1642 : { 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 1794 : owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept
1703 1794 : { return _M_refcount._M_less(__rhs._M_refcount); }
1704 :
1705 : void
1706 69 : reset() noexcept
1707 69 : { __weak_ptr().swap(*this); }
1708 :
1709 : void
1710 71 : swap(__weak_ptr& __s) noexcept
1711 : {
1712 71 : std::swap(_M_ptr, __s._M_ptr);
1713 71 : _M_refcount._M_swap(__s._M_refcount);
1714 71 : }
1715 :
1716 : private:
1717 : // Used by __enable_shared_from_this.
1718 : void
1719 7897 : _M_assign(_Tp* __ptr, const __shared_count<_Lp>& __refcount) noexcept
1720 : {
1721 7897 : if (use_count() == 0)
1722 : {
1723 7897 : _M_ptr = __ptr;
1724 7897 : _M_refcount = __refcount;
1725 : }
1726 7897 : }
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 7390 : operator()(const _Tp& __lhs, const _Tp& __rhs) const noexcept
1748 7390 : { 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
|