1 // shared_ptr and weak_ptr implementation details -*- C++ -*-
3 // Copyright (C) 2007-2016 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 // GCC Note: Based on files from version 1.32.0 of the Boost library.
28 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
31 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
32 // Copyright (C) 2001, 2002, 2003 Peter Dimov
35 // Copyright (C) 2001, 2002, 2003 Peter Dimov
37 // enable_shared_from_this.hpp
38 // Copyright (C) 2002 Peter Dimov
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)
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}
49 #ifndef _SHARED_PTR_BASE_H
50 #define _SHARED_PTR_BASE_H 1
55 #include <bits/allocated_ptr.h>
56 #include <bits/refwrap.h>
57 #include <bits/stl_function.h>
58 #include <ext/aligned_buffer.h>
60 namespace std
_GLIBCXX_VISIBILITY(default)
62 _GLIBCXX_BEGIN_NAMESPACE_VERSION
64 #if _GLIBCXX_USE_DEPRECATED
65 template<typename
> class auto_ptr
;
69 * @brief Exception possibly thrown by @c shared_ptr.
72 class bad_weak_ptr
: public std::exception
75 virtual char const* what() const noexcept
;
77 virtual ~bad_weak_ptr() noexcept
;
80 // Substitute for bad_weak_ptr object in the case of -fno-exceptions.
82 __throw_bad_weak_ptr()
83 { _GLIBCXX_THROW_OR_ABORT(bad_weak_ptr()); }
85 using __gnu_cxx::_Lock_policy
;
86 using __gnu_cxx::__default_lock_policy
;
87 using __gnu_cxx::_S_single
;
88 using __gnu_cxx::_S_mutex
;
89 using __gnu_cxx::_S_atomic
;
91 // Empty helper class except when the template argument is _S_mutex.
92 template<_Lock_policy _Lp
>
96 // The atomic policy uses fully-fenced builtins, single doesn't care.
97 enum { _S_need_barriers
= 0 };
101 class _Mutex_base
<_S_mutex
>
102 : public __gnu_cxx::__mutex
105 // This policy is used when atomic builtins are not available.
106 // The replacement atomic operations might not have the necessary
108 enum { _S_need_barriers
= 1 };
111 template<_Lock_policy _Lp
= __default_lock_policy
>
112 class _Sp_counted_base
113 : public _Mutex_base
<_Lp
>
116 _Sp_counted_base() noexcept
117 : _M_use_count(1), _M_weak_count(1) { }
120 ~_Sp_counted_base() noexcept
123 // Called when _M_use_count drops to zero, to release the resources
126 _M_dispose() noexcept
= 0;
128 // Called when _M_weak_count drops to zero.
130 _M_destroy() noexcept
134 _M_get_deleter(const std::type_info
&) noexcept
= 0;
138 { __gnu_cxx::__atomic_add_dispatch(&_M_use_count
, 1); }
144 _M_add_ref_lock_nothrow();
147 _M_release() noexcept
149 // Be race-detector-friendly. For more info see bits/c++config.
150 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count
);
151 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count
, -1) == 1)
153 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count
);
155 // There must be a memory barrier between dispose() and destroy()
156 // to ensure that the effects of dispose() are observed in the
157 // thread that runs destroy().
158 // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
159 if (_Mutex_base
<_Lp
>::_S_need_barriers
)
161 __atomic_thread_fence (__ATOMIC_ACQ_REL
);
164 // Be race-detector-friendly. For more info see bits/c++config.
165 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count
);
166 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count
,
169 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count
);
176 _M_weak_add_ref() noexcept
177 { __gnu_cxx::__atomic_add_dispatch(&_M_weak_count
, 1); }
180 _M_weak_release() noexcept
182 // Be race-detector-friendly. For more info see bits/c++config.
183 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count
);
184 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count
, -1) == 1)
186 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count
);
187 if (_Mutex_base
<_Lp
>::_S_need_barriers
)
190 // destroy() must observe results of dispose()
191 __atomic_thread_fence (__ATOMIC_ACQ_REL
);
198 _M_get_use_count() const noexcept
200 // No memory barrier is used here so there is no synchronization
201 // with other threads.
202 return __atomic_load_n(&_M_use_count
, __ATOMIC_RELAXED
);
206 _Sp_counted_base(_Sp_counted_base
const&) = delete;
207 _Sp_counted_base
& operator=(_Sp_counted_base
const&) = delete;
209 _Atomic_word _M_use_count
; // #shared
210 _Atomic_word _M_weak_count
; // #weak + (#shared != 0)
215 _Sp_counted_base
<_S_single
>::
218 if (_M_use_count
== 0)
219 __throw_bad_weak_ptr();
225 _Sp_counted_base
<_S_mutex
>::
228 __gnu_cxx::__scoped_lock
sentry(*this);
229 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count
, 1) == 0)
232 __throw_bad_weak_ptr();
238 _Sp_counted_base
<_S_atomic
>::
241 // Perform lock-free add-if-not-zero operation.
242 _Atomic_word __count
= _M_get_use_count();
246 __throw_bad_weak_ptr();
247 // Replace the current counter value with the old value + 1, as
248 // long as it's not changed meanwhile.
250 while (!__atomic_compare_exchange_n(&_M_use_count
, &__count
, __count
+ 1,
251 true, __ATOMIC_ACQ_REL
,
257 _Sp_counted_base
<_S_single
>::
258 _M_add_ref_lock_nothrow()
260 if (_M_use_count
== 0)
268 _Sp_counted_base
<_S_mutex
>::
269 _M_add_ref_lock_nothrow()
271 __gnu_cxx::__scoped_lock
sentry(*this);
272 if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count
, 1) == 0)
282 _Sp_counted_base
<_S_atomic
>::
283 _M_add_ref_lock_nothrow()
285 // Perform lock-free add-if-not-zero operation.
286 _Atomic_word __count
= _M_get_use_count();
291 // Replace the current counter value with the old value + 1, as
292 // long as it's not changed meanwhile.
294 while (!__atomic_compare_exchange_n(&_M_use_count
, &__count
, __count
+ 1,
295 true, __ATOMIC_ACQ_REL
,
302 _Sp_counted_base
<_S_single
>::_M_add_ref_copy()
307 _Sp_counted_base
<_S_single
>::_M_release() noexcept
309 if (--_M_use_count
== 0)
312 if (--_M_weak_count
== 0)
319 _Sp_counted_base
<_S_single
>::_M_weak_add_ref() noexcept
324 _Sp_counted_base
<_S_single
>::_M_weak_release() noexcept
326 if (--_M_weak_count
== 0)
332 _Sp_counted_base
<_S_single
>::_M_get_use_count() const noexcept
333 { return _M_use_count
; }
336 // Forward declarations.
337 template<typename _Tp
, _Lock_policy _Lp
= __default_lock_policy
>
340 template<typename _Tp
, _Lock_policy _Lp
= __default_lock_policy
>
343 template<typename _Tp
, _Lock_policy _Lp
= __default_lock_policy
>
344 class __enable_shared_from_this
;
346 template<typename _Tp
>
349 template<typename _Tp
>
352 template<typename _Tp
>
355 template<typename _Tp
>
356 class enable_shared_from_this
;
358 template<_Lock_policy _Lp
= __default_lock_policy
>
361 template<_Lock_policy _Lp
= __default_lock_policy
>
362 class __shared_count
;
365 // Counted ptr with no deleter or allocator support
366 template<typename _Ptr
, _Lock_policy _Lp
>
367 class _Sp_counted_ptr final
: public _Sp_counted_base
<_Lp
>
371 _Sp_counted_ptr(_Ptr __p
) noexcept
375 _M_dispose() noexcept
379 _M_destroy() noexcept
383 _M_get_deleter(const std::type_info
&) noexcept
386 _Sp_counted_ptr(const _Sp_counted_ptr
&) = delete;
387 _Sp_counted_ptr
& operator=(const _Sp_counted_ptr
&) = delete;
395 _Sp_counted_ptr
<nullptr_t
, _S_single
>::_M_dispose() noexcept
{ }
399 _Sp_counted_ptr
<nullptr_t
, _S_mutex
>::_M_dispose() noexcept
{ }
403 _Sp_counted_ptr
<nullptr_t
, _S_atomic
>::_M_dispose() noexcept
{ }
405 template<int _Nm
, typename _Tp
,
406 bool __use_ebo
= !__is_final(_Tp
) && __is_empty(_Tp
)>
407 struct _Sp_ebo_helper
;
409 /// Specialization using EBO.
410 template<int _Nm
, typename _Tp
>
411 struct _Sp_ebo_helper
<_Nm
, _Tp
, true> : private _Tp
413 explicit _Sp_ebo_helper(const _Tp
& __tp
) : _Tp(__tp
) { }
416 _S_get(_Sp_ebo_helper
& __eboh
) { return static_cast<_Tp
&>(__eboh
); }
419 /// Specialization not using EBO.
420 template<int _Nm
, typename _Tp
>
421 struct _Sp_ebo_helper
<_Nm
, _Tp
, false>
423 explicit _Sp_ebo_helper(const _Tp
& __tp
) : _M_tp(__tp
) { }
426 _S_get(_Sp_ebo_helper
& __eboh
)
427 { return __eboh
._M_tp
; }
433 // Support for custom deleter and/or allocator
434 template<typename _Ptr
, typename _Deleter
, typename _Alloc
, _Lock_policy _Lp
>
435 class _Sp_counted_deleter final
: public _Sp_counted_base
<_Lp
>
437 class _Impl
: _Sp_ebo_helper
<0, _Deleter
>, _Sp_ebo_helper
<1, _Alloc
>
439 typedef _Sp_ebo_helper
<0, _Deleter
> _Del_base
;
440 typedef _Sp_ebo_helper
<1, _Alloc
> _Alloc_base
;
443 _Impl(_Ptr __p
, _Deleter __d
, const _Alloc
& __a
) noexcept
444 : _M_ptr(__p
), _Del_base(__d
), _Alloc_base(__a
)
447 _Deleter
& _M_del() noexcept
{ return _Del_base::_S_get(*this); }
448 _Alloc
& _M_alloc() noexcept
{ return _Alloc_base::_S_get(*this); }
454 using __allocator_type
= __alloc_rebind
<_Alloc
, _Sp_counted_deleter
>;
456 // __d(__p) must not throw.
457 _Sp_counted_deleter(_Ptr __p
, _Deleter __d
) noexcept
458 : _M_impl(__p
, __d
, _Alloc()) { }
460 // __d(__p) must not throw.
461 _Sp_counted_deleter(_Ptr __p
, _Deleter __d
, const _Alloc
& __a
) noexcept
462 : _M_impl(__p
, __d
, __a
) { }
464 ~_Sp_counted_deleter() noexcept
{ }
467 _M_dispose() noexcept
468 { _M_impl
._M_del()(_M_impl
._M_ptr
); }
471 _M_destroy() noexcept
473 __allocator_type
__a(_M_impl
._M_alloc());
474 __allocated_ptr
<__allocator_type
> __guard_ptr
{ __a
, this };
475 this->~_Sp_counted_deleter();
479 _M_get_deleter(const std::type_info
& __ti
) noexcept
482 // _GLIBCXX_RESOLVE_LIB_DEFECTS
483 // 2400. shared_ptr's get_deleter() should use addressof()
484 return __ti
== typeid(_Deleter
)
485 ? std::__addressof(_M_impl
._M_del())
496 // helpers for make_shared / allocate_shared
498 struct _Sp_make_shared_tag
{ };
500 template<typename _Tp
, typename _Alloc
, _Lock_policy _Lp
>
501 class _Sp_counted_ptr_inplace final
: public _Sp_counted_base
<_Lp
>
503 class _Impl
: _Sp_ebo_helper
<0, _Alloc
>
505 typedef _Sp_ebo_helper
<0, _Alloc
> _A_base
;
508 explicit _Impl(_Alloc __a
) noexcept
: _A_base(__a
) { }
510 _Alloc
& _M_alloc() noexcept
{ return _A_base::_S_get(*this); }
512 __gnu_cxx::__aligned_buffer
<_Tp
> _M_storage
;
516 using __allocator_type
= __alloc_rebind
<_Alloc
, _Sp_counted_ptr_inplace
>;
518 template<typename
... _Args
>
519 _Sp_counted_ptr_inplace(_Alloc __a
, _Args
&&... __args
)
522 // _GLIBCXX_RESOLVE_LIB_DEFECTS
523 // 2070. allocate_shared should use allocator_traits<A>::construct
524 allocator_traits
<_Alloc
>::construct(__a
, _M_ptr(),
525 std::forward
<_Args
>(__args
)...); // might throw
528 ~_Sp_counted_ptr_inplace() noexcept
{ }
531 _M_dispose() noexcept
533 allocator_traits
<_Alloc
>::destroy(_M_impl
._M_alloc(), _M_ptr());
536 // Override because the allocator needs to know the dynamic type
538 _M_destroy() noexcept
540 __allocator_type
__a(_M_impl
._M_alloc());
541 __allocated_ptr
<__allocator_type
> __guard_ptr
{ __a
, this };
542 this->~_Sp_counted_ptr_inplace();
545 // Sneaky trick so __shared_ptr can get the managed pointer
547 _M_get_deleter(const std::type_info
& __ti
) noexcept
550 if (__ti
== typeid(_Sp_make_shared_tag
))
551 return const_cast<typename remove_cv
<_Tp
>::type
*>(_M_ptr());
557 _Tp
* _M_ptr() noexcept
{ return _M_impl
._M_storage
._M_ptr(); }
563 template<_Lock_policy _Lp
>
567 constexpr __shared_count() noexcept
: _M_pi(0)
570 template<typename _Ptr
>
572 __shared_count(_Ptr __p
) : _M_pi(0)
576 _M_pi
= new _Sp_counted_ptr
<_Ptr
, _Lp
>(__p
);
581 __throw_exception_again
;
585 template<typename _Ptr
, typename _Deleter
>
586 __shared_count(_Ptr __p
, _Deleter __d
)
587 : __shared_count(__p
, std::move(__d
), allocator
<void>())
590 template<typename _Ptr
, typename _Deleter
, typename _Alloc
>
591 __shared_count(_Ptr __p
, _Deleter __d
, _Alloc __a
) : _M_pi(0)
593 typedef _Sp_counted_deleter
<_Ptr
, _Deleter
, _Alloc
, _Lp
> _Sp_cd_type
;
596 typename
_Sp_cd_type::__allocator_type
__a2(__a
);
597 auto __guard
= std::__allocate_guarded(__a2
);
598 _Sp_cd_type
* __mem
= __guard
.get();
599 ::new (__mem
) _Sp_cd_type(__p
, std::move(__d
), std::move(__a
));
605 __d(__p
); // Call _Deleter on __p.
606 __throw_exception_again
;
610 template<typename _Tp
, typename _Alloc
, typename
... _Args
>
611 __shared_count(_Sp_make_shared_tag
, _Tp
*, const _Alloc
& __a
,
615 typedef _Sp_counted_ptr_inplace
<_Tp
, _Alloc
, _Lp
> _Sp_cp_type
;
616 typename
_Sp_cp_type::__allocator_type
__a2(__a
);
617 auto __guard
= std::__allocate_guarded(__a2
);
618 _Sp_cp_type
* __mem
= __guard
.get();
619 ::new (__mem
) _Sp_cp_type(std::move(__a
),
620 std::forward
<_Args
>(__args
)...);
625 #if _GLIBCXX_USE_DEPRECATED
626 // Special case for auto_ptr<_Tp> to provide the strong guarantee.
627 template<typename _Tp
>
629 __shared_count(std::auto_ptr
<_Tp
>&& __r
);
632 // Special case for unique_ptr<_Tp,_Del> to provide the strong guarantee.
633 template<typename _Tp
, typename _Del
>
635 __shared_count(std::unique_ptr
<_Tp
, _Del
>&& __r
) : _M_pi(0)
637 // _GLIBCXX_RESOLVE_LIB_DEFECTS
638 // 2415. Inconsistency between unique_ptr and shared_ptr
639 if (__r
.get() == nullptr)
642 using _Ptr
= typename unique_ptr
<_Tp
, _Del
>::pointer
;
643 using _Del2
= typename conditional
<is_reference
<_Del
>::value
,
644 reference_wrapper
<typename remove_reference
<_Del
>::type
>,
647 = _Sp_counted_deleter
<_Ptr
, _Del2
, allocator
<void>, _Lp
>;
648 using _Alloc
= allocator
<_Sp_cd_type
>;
649 using _Alloc_traits
= allocator_traits
<_Alloc
>;
651 _Sp_cd_type
* __mem
= _Alloc_traits::allocate(__a
, 1);
652 _Alloc_traits::construct(__a
, __mem
, __r
.release(),
653 __r
.get_deleter()); // non-throwing
657 // Throw bad_weak_ptr when __r._M_get_use_count() == 0.
658 explicit __shared_count(const __weak_count
<_Lp
>& __r
);
660 // Does not throw if __r._M_get_use_count() == 0, caller must check.
661 explicit __shared_count(const __weak_count
<_Lp
>& __r
, std::nothrow_t
);
663 ~__shared_count() noexcept
665 if (_M_pi
!= nullptr)
669 __shared_count(const __shared_count
& __r
) noexcept
673 _M_pi
->_M_add_ref_copy();
677 operator=(const __shared_count
& __r
) noexcept
679 _Sp_counted_base
<_Lp
>* __tmp
= __r
._M_pi
;
683 __tmp
->_M_add_ref_copy();
692 _M_swap(__shared_count
& __r
) noexcept
694 _Sp_counted_base
<_Lp
>* __tmp
= __r
._M_pi
;
700 _M_get_use_count() const noexcept
701 { return _M_pi
!= 0 ? _M_pi
->_M_get_use_count() : 0; }
704 _M_unique() const noexcept
705 { return this->_M_get_use_count() == 1; }
708 _M_get_deleter(const std::type_info
& __ti
) const noexcept
709 { return _M_pi
? _M_pi
->_M_get_deleter(__ti
) : nullptr; }
712 _M_less(const __shared_count
& __rhs
) const noexcept
713 { return std::less
<_Sp_counted_base
<_Lp
>*>()(this->_M_pi
, __rhs
._M_pi
); }
716 _M_less(const __weak_count
<_Lp
>& __rhs
) const noexcept
717 { return std::less
<_Sp_counted_base
<_Lp
>*>()(this->_M_pi
, __rhs
._M_pi
); }
719 // Friend function injected into enclosing namespace and found by ADL
721 operator==(const __shared_count
& __a
, const __shared_count
& __b
) noexcept
722 { return __a
._M_pi
== __b
._M_pi
; }
725 friend class __weak_count
<_Lp
>;
727 _Sp_counted_base
<_Lp
>* _M_pi
;
731 template<_Lock_policy _Lp
>
735 constexpr __weak_count() noexcept
: _M_pi(nullptr)
738 __weak_count(const __shared_count
<_Lp
>& __r
) noexcept
741 if (_M_pi
!= nullptr)
742 _M_pi
->_M_weak_add_ref();
745 __weak_count(const __weak_count
& __r
) noexcept
748 if (_M_pi
!= nullptr)
749 _M_pi
->_M_weak_add_ref();
752 __weak_count(__weak_count
&& __r
) noexcept
754 { __r
._M_pi
= nullptr; }
756 ~__weak_count() noexcept
758 if (_M_pi
!= nullptr)
759 _M_pi
->_M_weak_release();
763 operator=(const __shared_count
<_Lp
>& __r
) noexcept
765 _Sp_counted_base
<_Lp
>* __tmp
= __r
._M_pi
;
766 if (__tmp
!= nullptr)
767 __tmp
->_M_weak_add_ref();
768 if (_M_pi
!= nullptr)
769 _M_pi
->_M_weak_release();
775 operator=(const __weak_count
& __r
) noexcept
777 _Sp_counted_base
<_Lp
>* __tmp
= __r
._M_pi
;
778 if (__tmp
!= nullptr)
779 __tmp
->_M_weak_add_ref();
780 if (_M_pi
!= nullptr)
781 _M_pi
->_M_weak_release();
787 operator=(__weak_count
&& __r
) noexcept
789 if (_M_pi
!= nullptr)
790 _M_pi
->_M_weak_release();
797 _M_swap(__weak_count
& __r
) noexcept
799 _Sp_counted_base
<_Lp
>* __tmp
= __r
._M_pi
;
805 _M_get_use_count() const noexcept
806 { return _M_pi
!= nullptr ? _M_pi
->_M_get_use_count() : 0; }
809 _M_less(const __weak_count
& __rhs
) const noexcept
810 { return std::less
<_Sp_counted_base
<_Lp
>*>()(this->_M_pi
, __rhs
._M_pi
); }
813 _M_less(const __shared_count
<_Lp
>& __rhs
) const noexcept
814 { return std::less
<_Sp_counted_base
<_Lp
>*>()(this->_M_pi
, __rhs
._M_pi
); }
816 // Friend function injected into enclosing namespace and found by ADL
818 operator==(const __weak_count
& __a
, const __weak_count
& __b
) noexcept
819 { return __a
._M_pi
== __b
._M_pi
; }
822 friend class __shared_count
<_Lp
>;
824 _Sp_counted_base
<_Lp
>* _M_pi
;
827 // Now that __weak_count is defined we can define this constructor:
828 template<_Lock_policy _Lp
>
830 __shared_count
<_Lp
>::__shared_count(const __weak_count
<_Lp
>& __r
)
833 if (_M_pi
!= nullptr)
834 _M_pi
->_M_add_ref_lock();
836 __throw_bad_weak_ptr();
839 // Now that __weak_count is defined we can define this constructor:
840 template<_Lock_policy _Lp
>
842 __shared_count
<_Lp
>::
843 __shared_count(const __weak_count
<_Lp
>& __r
, std::nothrow_t
)
846 if (_M_pi
!= nullptr)
847 if (!_M_pi
->_M_add_ref_lock_nothrow())
851 // Helper traits for shared_ptr
853 template<typename _Yp_ptr
, typename _Tp_ptr
>
854 struct __sp_compatible_with
858 template<typename _Yp
, typename _Tp
>
859 struct __sp_compatible_with
<_Yp
*, _Tp
*>
860 : is_convertible
<_Yp
*, _Tp
*>::type
863 template<typename _Tp
, _Lock_policy _Lp
>
867 using element_type
= _Tp
;
870 // Trait to check if shared_ptr<T> can be constructed from Y*.
871 template<typename _Tp1
, typename _Yp
>
872 using __sp_is_constructible
= is_convertible
<_Yp
*, _Tp1
*>;
874 // Constraint for taking ownership of a pointer of type _Yp*:
875 template<typename _Yp
>
877 = typename enable_if
<__sp_is_constructible
<_Tp
, _Yp
>::value
>::type
;
879 // Constraint for construction from shared_ptr and weak_ptr:
880 template<typename _Yp
, typename _Res
= void>
881 using _Compatible
= typename
882 enable_if
<__sp_compatible_with
<_Yp
*, _Tp
*>::value
, _Res
>::type
;
884 // Constraint for assignment from shared_ptr and weak_ptr:
885 template<typename _Yp
>
886 using _Assignable
= _Compatible
<_Yp
, __shared_ptr
&>;
888 // Constraint for construction from unique_ptr:
889 template<typename _Yp
, typename _Del
, typename _Res
= void,
890 typename _Ptr
= typename unique_ptr
<_Yp
, _Del
>::pointer
>
891 using _UniqCompatible
= typename enable_if
<
892 is_convertible
<_Ptr
, element_type
*>::value
895 // Constraint for assignment from unique_ptr:
896 template<typename _Yp
, typename _Del
>
897 using _UniqAssignable
= _UniqCompatible
<_Yp
, _Del
, __shared_ptr
&>;
901 #if __cplusplus > 201402L
902 using weak_type
= __weak_ptr
<_Tp
, _Lp
>;
905 constexpr __shared_ptr() noexcept
906 : _M_ptr(0), _M_refcount()
909 template<typename _Yp
, typename
= _SafeConv
<_Yp
>>
911 __shared_ptr(_Yp
* __p
)
912 : _M_ptr(__p
), _M_refcount(__p
)
914 static_assert( !is_void
<_Yp
>::value
, "incomplete type" );
915 static_assert( sizeof(_Yp
) > 0, "incomplete type" );
916 _M_enable_shared_from_this_with(__p
);
919 template<typename _Yp
, typename _Deleter
, typename
= _SafeConv
<_Yp
>>
920 __shared_ptr(_Yp
* __p
, _Deleter __d
)
921 : _M_ptr(__p
), _M_refcount(__p
, __d
)
923 static_assert(__is_callable
<_Deleter(_Yp
*)>::value
,
924 "deleter expression d(p) is well-formed");
925 _M_enable_shared_from_this_with(__p
);
928 template<typename _Yp
, typename _Deleter
, typename _Alloc
,
929 typename
= _SafeConv
<_Yp
>>
930 __shared_ptr(_Yp
* __p
, _Deleter __d
, _Alloc __a
)
931 : _M_ptr(__p
), _M_refcount(__p
, __d
, std::move(__a
))
933 static_assert(__is_callable
<_Deleter(_Yp
*)>::value
,
934 "deleter expression d(p) is well-formed");
935 _M_enable_shared_from_this_with(__p
);
938 template<typename _Deleter
>
939 __shared_ptr(nullptr_t __p
, _Deleter __d
)
940 : _M_ptr(0), _M_refcount(__p
, __d
)
943 template<typename _Deleter
, typename _Alloc
>
944 __shared_ptr(nullptr_t __p
, _Deleter __d
, _Alloc __a
)
945 : _M_ptr(0), _M_refcount(__p
, __d
, std::move(__a
))
948 template<typename _Yp
>
949 __shared_ptr(const __shared_ptr
<_Yp
, _Lp
>& __r
,
950 element_type
* __p
) noexcept
951 : _M_ptr(__p
), _M_refcount(__r
._M_refcount
) // never throws
954 __shared_ptr(const __shared_ptr
&) noexcept
= default;
955 __shared_ptr
& operator=(const __shared_ptr
&) noexcept
= default;
956 ~__shared_ptr() = default;
958 template<typename _Yp
, typename
= _Compatible
<_Yp
>>
959 __shared_ptr(const __shared_ptr
<_Yp
, _Lp
>& __r
) noexcept
960 : _M_ptr(__r
._M_ptr
), _M_refcount(__r
._M_refcount
)
963 __shared_ptr(__shared_ptr
&& __r
) noexcept
964 : _M_ptr(__r
._M_ptr
), _M_refcount()
966 _M_refcount
._M_swap(__r
._M_refcount
);
970 template<typename _Yp
, typename
= _Compatible
<_Yp
>>
971 __shared_ptr(__shared_ptr
<_Yp
, _Lp
>&& __r
) noexcept
972 : _M_ptr(__r
._M_ptr
), _M_refcount()
974 _M_refcount
._M_swap(__r
._M_refcount
);
978 template<typename _Yp
, typename
= _Compatible
<_Yp
>>
979 explicit __shared_ptr(const __weak_ptr
<_Yp
, _Lp
>& __r
)
980 : _M_refcount(__r
._M_refcount
) // may throw
982 // It is now safe to copy __r._M_ptr, as
983 // _M_refcount(__r._M_refcount) did not throw.
987 // If an exception is thrown this constructor has no effect.
988 template<typename _Yp
, typename _Del
,
989 typename
= _UniqCompatible
<_Yp
, _Del
>>
990 __shared_ptr(unique_ptr
<_Yp
, _Del
>&& __r
)
991 : _M_ptr(__r
.get()), _M_refcount()
993 auto __raw
= _S_raw_ptr(__r
.get());
994 _M_refcount
= __shared_count
<_Lp
>(std::move(__r
));
995 _M_enable_shared_from_this_with(__raw
);
998 #if _GLIBCXX_USE_DEPRECATED
999 // Postcondition: use_count() == 1 and __r.get() == 0
1000 template<typename _Yp
, typename
= _Compatible
<_Yp
>>
1001 __shared_ptr(auto_ptr
<_Yp
>&& __r
);
1004 constexpr __shared_ptr(nullptr_t
) noexcept
: __shared_ptr() { }
1006 template<typename _Yp
>
1008 operator=(const __shared_ptr
<_Yp
, _Lp
>& __r
) noexcept
1010 _M_ptr
= __r
._M_ptr
;
1011 _M_refcount
= __r
._M_refcount
; // __shared_count::op= doesn't throw
1015 #if _GLIBCXX_USE_DEPRECATED
1016 template<typename _Yp
>
1018 operator=(auto_ptr
<_Yp
>&& __r
)
1020 __shared_ptr(std::move(__r
)).swap(*this);
1026 operator=(__shared_ptr
&& __r
) noexcept
1028 __shared_ptr(std::move(__r
)).swap(*this);
1034 operator=(__shared_ptr
<_Yp
, _Lp
>&& __r
) noexcept
1036 __shared_ptr(std::move(__r
)).swap(*this);
1040 template<typename _Yp
, typename _Del
>
1041 _UniqAssignable
<_Yp
, _Del
>
1042 operator=(unique_ptr
<_Yp
, _Del
>&& __r
)
1044 __shared_ptr(std::move(__r
)).swap(*this);
1050 { __shared_ptr().swap(*this); }
1052 template<typename _Yp
>
1054 reset(_Yp
* __p
) // _Yp must be complete.
1056 // Catch self-reset errors.
1057 __glibcxx_assert(__p
== 0 || __p
!= _M_ptr
);
1058 __shared_ptr(__p
).swap(*this);
1061 template<typename _Yp
, typename _Deleter
>
1063 reset(_Yp
* __p
, _Deleter __d
)
1064 { __shared_ptr(__p
, __d
).swap(*this); }
1066 template<typename _Yp
, typename _Deleter
, typename _Alloc
>
1068 reset(_Yp
* __p
, _Deleter __d
, _Alloc __a
)
1069 { __shared_ptr(__p
, __d
, std::move(__a
)).swap(*this); }
1071 // Allow class instantiation when _Tp is [cv-qual] void.
1072 typename
std::add_lvalue_reference
<element_type
>::type
1073 operator*() const noexcept
1075 __glibcxx_assert(_M_ptr
!= 0);
1080 operator->() const noexcept
1082 _GLIBCXX_DEBUG_PEDASSERT(_M_ptr
!= 0);
1087 get() const noexcept
1090 explicit operator bool() const // never throws
1091 { return _M_ptr
== 0 ? false : true; }
1094 unique() const noexcept
1095 { return _M_refcount
._M_unique(); }
1098 use_count() const noexcept
1099 { return _M_refcount
._M_get_use_count(); }
1102 swap(__shared_ptr
<_Tp
, _Lp
>& __other
) noexcept
1104 std::swap(_M_ptr
, __other
._M_ptr
);
1105 _M_refcount
._M_swap(__other
._M_refcount
);
1108 template<typename _Tp1
>
1110 owner_before(__shared_ptr
<_Tp1
, _Lp
> const& __rhs
) const
1111 { return _M_refcount
._M_less(__rhs
._M_refcount
); }
1113 template<typename _Tp1
>
1115 owner_before(__weak_ptr
<_Tp1
, _Lp
> const& __rhs
) const
1116 { return _M_refcount
._M_less(__rhs
._M_refcount
); }
1120 // This constructor is non-standard, it is used by allocate_shared.
1121 template<typename _Alloc
, typename
... _Args
>
1122 __shared_ptr(_Sp_make_shared_tag __tag
, const _Alloc
& __a
,
1124 : _M_ptr(), _M_refcount(__tag
, (_Tp
*)0, __a
,
1125 std::forward
<_Args
>(__args
)...)
1127 // _M_ptr needs to point to the newly constructed object.
1128 // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
1129 void* __p
= _M_refcount
._M_get_deleter(typeid(__tag
));
1130 _M_ptr
= static_cast<_Tp
*>(__p
);
1131 _M_enable_shared_from_this_with(_M_ptr
);
1134 template<typename _Alloc
>
1137 void operator()(typename
_Alloc::value_type
* __ptr
)
1139 __allocated_ptr
<_Alloc
> __guard
{ _M_alloc
, __ptr
};
1140 allocator_traits
<_Alloc
>::destroy(_M_alloc
, __guard
.get());
1145 template<typename _Alloc
, typename
... _Args
>
1146 __shared_ptr(_Sp_make_shared_tag __tag
, const _Alloc
& __a
,
1148 : _M_ptr(), _M_refcount()
1150 typedef typename allocator_traits
<_Alloc
>::template
1151 rebind_traits
<typename
std::remove_cv
<_Tp
>::type
> __traits
;
1152 _Deleter
<typename
__traits::allocator_type
> __del
= { __a
};
1153 auto __guard
= std::__allocate_guarded(__del
._M_alloc
);
1154 auto __ptr
= __guard
.get();
1155 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1156 // 2070. allocate_shared should use allocator_traits<A>::construct
1157 __traits::construct(__del
._M_alloc
, __ptr
,
1158 std::forward
<_Args
>(__args
)...);
1160 __shared_count
<_Lp
> __count(__ptr
, __del
, __del
._M_alloc
);
1161 _M_refcount
._M_swap(__count
);
1163 _M_enable_shared_from_this_with(_M_ptr
);
1167 template<typename _Tp1
, _Lock_policy _Lp1
, typename _Alloc
,
1169 friend __shared_ptr
<_Tp1
, _Lp1
>
1170 __allocate_shared(const _Alloc
& __a
, _Args
&&... __args
);
1172 // This constructor is used by __weak_ptr::lock() and
1173 // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
1174 __shared_ptr(const __weak_ptr
<_Tp
, _Lp
>& __r
, std::nothrow_t
)
1175 : _M_refcount(__r
._M_refcount
, std::nothrow
)
1177 _M_ptr
= _M_refcount
._M_get_use_count() ? __r
._M_ptr
: nullptr;
1180 friend class __weak_ptr
<_Tp
, _Lp
>;
1184 template<typename _Yp
>
1185 using __esft_base_t
= decltype(__enable_shared_from_this_base(
1186 std::declval
<const __shared_count
<_Lp
>&>(),
1187 std::declval
<_Yp
*>()));
1189 // Detect an accessible and unambiguous enable_shared_from_this base.
1190 template<typename _Yp
, typename
= void>
1191 struct __has_esft_base
1194 template<typename _Yp
>
1195 struct __has_esft_base
<_Yp
, __void_t
<__esft_base_t
<_Yp
>>>
1198 template<typename _Yp
>
1199 typename enable_if
<__has_esft_base
<_Yp
>::value
>::type
1200 _M_enable_shared_from_this_with(const _Yp
* __p
) noexcept
1202 if (auto __base
= __enable_shared_from_this_base(_M_refcount
, __p
))
1203 __base
->_M_weak_assign(const_cast<_Yp
*>(__p
), _M_refcount
);
1206 template<typename _Yp
>
1207 typename enable_if
<!__has_esft_base
<_Yp
>::value
>::type
1208 _M_enable_shared_from_this_with(const _Yp
*) noexcept
1212 _M_get_deleter(const std::type_info
& __ti
) const noexcept
1213 { return _M_refcount
._M_get_deleter(__ti
); }
1215 template<typename _Tp1
>
1217 _S_raw_ptr(_Tp1
* __ptr
)
1220 template<typename _Tp1
>
1222 _S_raw_ptr(_Tp1 __ptr
) -> decltype(std::__addressof(*__ptr
))
1223 { return std::__addressof(*__ptr
); }
1225 template<typename _Tp1
, _Lock_policy _Lp1
> friend class __shared_ptr
;
1226 template<typename _Tp1
, _Lock_policy _Lp1
> friend class __weak_ptr
;
1228 template<typename _Del
, typename _Tp1
, _Lock_policy _Lp1
>
1229 friend _Del
* get_deleter(const __shared_ptr
<_Tp1
, _Lp1
>&) noexcept
;
1231 element_type
* _M_ptr
; // Contained pointer.
1232 __shared_count
<_Lp
> _M_refcount
; // Reference counter.
1236 // 20.7.2.2.7 shared_ptr comparisons
1237 template<typename _Tp1
, typename _Tp2
, _Lock_policy _Lp
>
1239 operator==(const __shared_ptr
<_Tp1
, _Lp
>& __a
,
1240 const __shared_ptr
<_Tp2
, _Lp
>& __b
) noexcept
1241 { return __a
.get() == __b
.get(); }
1243 template<typename _Tp
, _Lock_policy _Lp
>
1245 operator==(const __shared_ptr
<_Tp
, _Lp
>& __a
, nullptr_t
) noexcept
1248 template<typename _Tp
, _Lock_policy _Lp
>
1250 operator==(nullptr_t
, const __shared_ptr
<_Tp
, _Lp
>& __a
) noexcept
1253 template<typename _Tp1
, typename _Tp2
, _Lock_policy _Lp
>
1255 operator!=(const __shared_ptr
<_Tp1
, _Lp
>& __a
,
1256 const __shared_ptr
<_Tp2
, _Lp
>& __b
) noexcept
1257 { return __a
.get() != __b
.get(); }
1259 template<typename _Tp
, _Lock_policy _Lp
>
1261 operator!=(const __shared_ptr
<_Tp
, _Lp
>& __a
, nullptr_t
) noexcept
1262 { return (bool)__a
; }
1264 template<typename _Tp
, _Lock_policy _Lp
>
1266 operator!=(nullptr_t
, const __shared_ptr
<_Tp
, _Lp
>& __a
) noexcept
1267 { return (bool)__a
; }
1269 template<typename _Tp
, typename _Up
, _Lock_policy _Lp
>
1271 operator<(const __shared_ptr
<_Tp
, _Lp
>& __a
,
1272 const __shared_ptr
<_Up
, _Lp
>& __b
) noexcept
1274 using _Tp_elt
= typename __shared_ptr
<_Tp
, _Lp
>::element_type
;
1275 using _Up_elt
= typename __shared_ptr
<_Up
, _Lp
>::element_type
;
1276 using _Vp
= typename common_type
<_Tp_elt
*, _Up_elt
*>::type
;
1277 return less
<_Vp
>()(__a
.get(), __b
.get());
1280 template<typename _Tp
, _Lock_policy _Lp
>
1282 operator<(const __shared_ptr
<_Tp
, _Lp
>& __a
, nullptr_t
) noexcept
1284 using _Tp_elt
= typename __shared_ptr
<_Tp
, _Lp
>::element_type
;
1285 return less
<_Tp_elt
*>()(__a
.get(), nullptr);
1288 template<typename _Tp
, _Lock_policy _Lp
>
1290 operator<(nullptr_t
, const __shared_ptr
<_Tp
, _Lp
>& __a
) noexcept
1292 using _Tp_elt
= typename __shared_ptr
<_Tp
, _Lp
>::element_type
;
1293 return less
<_Tp_elt
*>()(nullptr, __a
.get());
1296 template<typename _Tp1
, typename _Tp2
, _Lock_policy _Lp
>
1298 operator<=(const __shared_ptr
<_Tp1
, _Lp
>& __a
,
1299 const __shared_ptr
<_Tp2
, _Lp
>& __b
) noexcept
1300 { return !(__b
< __a
); }
1302 template<typename _Tp
, _Lock_policy _Lp
>
1304 operator<=(const __shared_ptr
<_Tp
, _Lp
>& __a
, nullptr_t
) noexcept
1305 { return !(nullptr < __a
); }
1307 template<typename _Tp
, _Lock_policy _Lp
>
1309 operator<=(nullptr_t
, const __shared_ptr
<_Tp
, _Lp
>& __a
) noexcept
1310 { return !(__a
< nullptr); }
1312 template<typename _Tp1
, typename _Tp2
, _Lock_policy _Lp
>
1314 operator>(const __shared_ptr
<_Tp1
, _Lp
>& __a
,
1315 const __shared_ptr
<_Tp2
, _Lp
>& __b
) noexcept
1316 { return (__b
< __a
); }
1318 template<typename _Tp
, _Lock_policy _Lp
>
1320 operator>(const __shared_ptr
<_Tp
, _Lp
>& __a
, nullptr_t
) noexcept
1321 { return nullptr < __a
; }
1323 template<typename _Tp
, _Lock_policy _Lp
>
1325 operator>(nullptr_t
, const __shared_ptr
<_Tp
, _Lp
>& __a
) noexcept
1326 { return __a
< nullptr; }
1328 template<typename _Tp1
, typename _Tp2
, _Lock_policy _Lp
>
1330 operator>=(const __shared_ptr
<_Tp1
, _Lp
>& __a
,
1331 const __shared_ptr
<_Tp2
, _Lp
>& __b
) noexcept
1332 { return !(__a
< __b
); }
1334 template<typename _Tp
, _Lock_policy _Lp
>
1336 operator>=(const __shared_ptr
<_Tp
, _Lp
>& __a
, nullptr_t
) noexcept
1337 { return !(__a
< nullptr); }
1339 template<typename _Tp
, _Lock_policy _Lp
>
1341 operator>=(nullptr_t
, const __shared_ptr
<_Tp
, _Lp
>& __a
) noexcept
1342 { return !(nullptr < __a
); }
1344 template<typename _Sp
>
1345 struct _Sp_less
: public binary_function
<_Sp
, _Sp
, bool>
1348 operator()(const _Sp
& __lhs
, const _Sp
& __rhs
) const noexcept
1350 typedef typename
_Sp::element_type element_type
;
1351 return std::less
<element_type
*>()(__lhs
.get(), __rhs
.get());
1355 template<typename _Tp
, _Lock_policy _Lp
>
1356 struct less
<__shared_ptr
<_Tp
, _Lp
>>
1357 : public _Sp_less
<__shared_ptr
<_Tp
, _Lp
>>
1360 // 20.7.2.2.8 shared_ptr specialized algorithms.
1361 template<typename _Tp
, _Lock_policy _Lp
>
1363 swap(__shared_ptr
<_Tp
, _Lp
>& __a
, __shared_ptr
<_Tp
, _Lp
>& __b
) noexcept
1366 // 20.7.2.2.9 shared_ptr casts
1368 // The seemingly equivalent code:
1369 // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
1370 // will eventually result in undefined behaviour, attempting to
1371 // delete the same object twice.
1372 /// static_pointer_cast
1373 template<typename _Tp
, typename _Tp1
, _Lock_policy _Lp
>
1374 inline __shared_ptr
<_Tp
, _Lp
>
1375 static_pointer_cast(const __shared_ptr
<_Tp1
, _Lp
>& __r
) noexcept
1377 using _Sp
= __shared_ptr
<_Tp
, _Lp
>;
1378 return _Sp(__r
, static_cast<typename
_Sp::element_type
*>(__r
.get()));
1381 // The seemingly equivalent code:
1382 // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
1383 // will eventually result in undefined behaviour, attempting to
1384 // delete the same object twice.
1385 /// const_pointer_cast
1386 template<typename _Tp
, typename _Tp1
, _Lock_policy _Lp
>
1387 inline __shared_ptr
<_Tp
, _Lp
>
1388 const_pointer_cast(const __shared_ptr
<_Tp1
, _Lp
>& __r
) noexcept
1390 using _Sp
= __shared_ptr
<_Tp
, _Lp
>;
1391 return _Sp(__r
, const_cast<typename
_Sp::element_type
*>(__r
.get()));
1394 // The seemingly equivalent code:
1395 // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
1396 // will eventually result in undefined behaviour, attempting to
1397 // delete the same object twice.
1398 /// dynamic_pointer_cast
1399 template<typename _Tp
, typename _Tp1
, _Lock_policy _Lp
>
1400 inline __shared_ptr
<_Tp
, _Lp
>
1401 dynamic_pointer_cast(const __shared_ptr
<_Tp1
, _Lp
>& __r
) noexcept
1403 using _Sp
= __shared_ptr
<_Tp
, _Lp
>;
1404 if (auto* __p
= dynamic_cast<typename
_Sp::element_type
*>(__r
.get()))
1405 return _Sp(__r
, __p
);
1409 #if __cplusplus > 201402L
1410 template<typename _Tp
, typename _Tp1
, _Lock_policy _Lp
>
1411 inline __shared_ptr
<_Tp
, _Lp
>
1412 reinterpret_pointer_cast(const __shared_ptr
<_Tp1
, _Lp
>& __r
) noexcept
1414 using _Sp
= __shared_ptr
<_Tp
, _Lp
>;
1415 return _Sp(__r
, reinterpret_cast<typename
_Sp::element_type
*>(__r
.get()));
1419 template<typename _Tp
, _Lock_policy _Lp
>
1422 template<typename _Yp
, typename _Res
= void>
1423 using _Compatible
= typename
1424 enable_if
<__sp_compatible_with
<_Yp
*, _Tp
*>::value
, _Res
>::type
;
1426 // Constraint for assignment from shared_ptr and weak_ptr:
1427 template<typename _Yp
>
1428 using _Assignable
= _Compatible
<_Yp
, __weak_ptr
&>;
1431 using element_type
= _Tp
;
1433 constexpr __weak_ptr() noexcept
1434 : _M_ptr(nullptr), _M_refcount()
1437 __weak_ptr(const __weak_ptr
&) noexcept
= default;
1439 ~__weak_ptr() = default;
1441 // The "obvious" converting constructor implementation:
1443 // template<typename _Tp1>
1444 // __weak_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
1445 // : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount) // never throws
1448 // has a serious problem.
1450 // __r._M_ptr may already have been invalidated. The _M_ptr(__r._M_ptr)
1451 // conversion may require access to *__r._M_ptr (virtual inheritance).
1453 // It is not possible to avoid spurious access violations since
1454 // in multithreaded programs __r._M_ptr may be invalidated at any point.
1455 template<typename _Yp
, typename
= _Compatible
<_Yp
>>
1456 __weak_ptr(const __weak_ptr
<_Yp
, _Lp
>& __r
) noexcept
1457 : _M_refcount(__r
._M_refcount
)
1458 { _M_ptr
= __r
.lock().get(); }
1460 template<typename _Yp
, typename
= _Compatible
<_Yp
>>
1461 __weak_ptr(const __shared_ptr
<_Yp
, _Lp
>& __r
) noexcept
1462 : _M_ptr(__r
._M_ptr
), _M_refcount(__r
._M_refcount
)
1465 __weak_ptr(__weak_ptr
&& __r
) noexcept
1466 : _M_ptr(__r
._M_ptr
), _M_refcount(std::move(__r
._M_refcount
))
1467 { __r
._M_ptr
= nullptr; }
1469 template<typename _Yp
, typename
= _Compatible
<_Yp
>>
1470 __weak_ptr(__weak_ptr
<_Yp
, _Lp
>&& __r
) noexcept
1471 : _M_ptr(__r
.lock().get()), _M_refcount(std::move(__r
._M_refcount
))
1472 { __r
._M_ptr
= nullptr; }
1475 operator=(const __weak_ptr
& __r
) noexcept
= default;
1477 template<typename _Yp
>
1479 operator=(const __weak_ptr
<_Yp
, _Lp
>& __r
) noexcept
1481 _M_ptr
= __r
.lock().get();
1482 _M_refcount
= __r
._M_refcount
;
1486 template<typename _Yp
>
1488 operator=(const __shared_ptr
<_Yp
, _Lp
>& __r
) noexcept
1490 _M_ptr
= __r
._M_ptr
;
1491 _M_refcount
= __r
._M_refcount
;
1496 operator=(__weak_ptr
&& __r
) noexcept
1498 _M_ptr
= __r
._M_ptr
;
1499 _M_refcount
= std::move(__r
._M_refcount
);
1500 __r
._M_ptr
= nullptr;
1504 template<typename _Yp
>
1506 operator=(__weak_ptr
<_Yp
, _Lp
>&& __r
) noexcept
1508 _M_ptr
= __r
.lock().get();
1509 _M_refcount
= std::move(__r
._M_refcount
);
1510 __r
._M_ptr
= nullptr;
1514 __shared_ptr
<_Tp
, _Lp
>
1515 lock() const noexcept
1516 { return __shared_ptr
<element_type
, _Lp
>(*this, std::nothrow
); }
1519 use_count() const noexcept
1520 { return _M_refcount
._M_get_use_count(); }
1523 expired() const noexcept
1524 { return _M_refcount
._M_get_use_count() == 0; }
1526 template<typename _Tp1
>
1528 owner_before(const __shared_ptr
<_Tp1
, _Lp
>& __rhs
) const
1529 { return _M_refcount
._M_less(__rhs
._M_refcount
); }
1531 template<typename _Tp1
>
1533 owner_before(const __weak_ptr
<_Tp1
, _Lp
>& __rhs
) const
1534 { return _M_refcount
._M_less(__rhs
._M_refcount
); }
1538 { __weak_ptr().swap(*this); }
1541 swap(__weak_ptr
& __s
) noexcept
1543 std::swap(_M_ptr
, __s
._M_ptr
);
1544 _M_refcount
._M_swap(__s
._M_refcount
);
1548 // Used by __enable_shared_from_this.
1550 _M_assign(_Tp
* __ptr
, const __shared_count
<_Lp
>& __refcount
) noexcept
1552 if (use_count() == 0)
1555 _M_refcount
= __refcount
;
1559 template<typename _Tp1
, _Lock_policy _Lp1
> friend class __shared_ptr
;
1560 template<typename _Tp1
, _Lock_policy _Lp1
> friend class __weak_ptr
;
1561 friend class __enable_shared_from_this
<_Tp
, _Lp
>;
1562 friend class enable_shared_from_this
<_Tp
>;
1564 element_type
* _M_ptr
; // Contained pointer.
1565 __weak_count
<_Lp
> _M_refcount
; // Reference counter.
1568 // 20.7.2.3.6 weak_ptr specialized algorithms.
1569 template<typename _Tp
, _Lock_policy _Lp
>
1571 swap(__weak_ptr
<_Tp
, _Lp
>& __a
, __weak_ptr
<_Tp
, _Lp
>& __b
) noexcept
1574 template<typename _Tp
, typename _Tp1
>
1575 struct _Sp_owner_less
: public binary_function
<_Tp
, _Tp
, bool>
1578 operator()(const _Tp
& __lhs
, const _Tp
& __rhs
) const
1579 { return __lhs
.owner_before(__rhs
); }
1582 operator()(const _Tp
& __lhs
, const _Tp1
& __rhs
) const
1583 { return __lhs
.owner_before(__rhs
); }
1586 operator()(const _Tp1
& __lhs
, const _Tp
& __rhs
) const
1587 { return __lhs
.owner_before(__rhs
); }
1591 struct _Sp_owner_less
<void, void>
1593 template<typename _Tp
, typename _Up
>
1595 operator()(const _Tp
& __lhs
, const _Up
& __rhs
) const
1596 -> decltype(__lhs
.owner_before(__rhs
))
1597 { return __lhs
.owner_before(__rhs
); }
1599 using is_transparent
= void;
1602 template<typename _Tp
, _Lock_policy _Lp
>
1603 struct owner_less
<__shared_ptr
<_Tp
, _Lp
>>
1604 : public _Sp_owner_less
<__shared_ptr
<_Tp
, _Lp
>, __weak_ptr
<_Tp
, _Lp
>>
1607 template<typename _Tp
, _Lock_policy _Lp
>
1608 struct owner_less
<__weak_ptr
<_Tp
, _Lp
>>
1609 : public _Sp_owner_less
<__weak_ptr
<_Tp
, _Lp
>, __shared_ptr
<_Tp
, _Lp
>>
1613 template<typename _Tp
, _Lock_policy _Lp
>
1614 class __enable_shared_from_this
1617 constexpr __enable_shared_from_this() noexcept
{ }
1619 __enable_shared_from_this(const __enable_shared_from_this
&) noexcept
{ }
1621 __enable_shared_from_this
&
1622 operator=(const __enable_shared_from_this
&) noexcept
1625 ~__enable_shared_from_this() { }
1628 __shared_ptr
<_Tp
, _Lp
>
1630 { return __shared_ptr
<_Tp
, _Lp
>(this->_M_weak_this
); }
1632 __shared_ptr
<const _Tp
, _Lp
>
1633 shared_from_this() const
1634 { return __shared_ptr
<const _Tp
, _Lp
>(this->_M_weak_this
); }
1636 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1637 __weak_ptr
<_Tp
, _Lp
>
1638 weak_from_this() noexcept
1639 { return this->_M_weak_this
; }
1641 __weak_ptr
<const _Tp
, _Lp
>
1642 weak_from_this() const noexcept
1643 { return this->_M_weak_this
; }
1647 template<typename _Tp1
>
1649 _M_weak_assign(_Tp1
* __p
, const __shared_count
<_Lp
>& __n
) const noexcept
1650 { _M_weak_this
._M_assign(__p
, __n
); }
1653 __enable_shared_from_this_base(const __shared_count
<_Lp
>&,
1654 const __enable_shared_from_this
* __p
)
1657 mutable __weak_ptr
<_Tp
, _Lp
> _M_weak_this
;
1660 template<typename _Tp
, _Lock_policy _Lp
, typename _Alloc
, typename
... _Args
>
1661 inline __shared_ptr
<_Tp
, _Lp
>
1662 __allocate_shared(const _Alloc
& __a
, _Args
&&... __args
)
1664 return __shared_ptr
<_Tp
, _Lp
>(_Sp_make_shared_tag(), __a
,
1665 std::forward
<_Args
>(__args
)...);
1668 template<typename _Tp
, _Lock_policy _Lp
, typename
... _Args
>
1669 inline __shared_ptr
<_Tp
, _Lp
>
1670 __make_shared(_Args
&&... __args
)
1672 typedef typename
std::remove_const
<_Tp
>::type _Tp_nc
;
1673 return std::__allocate_shared
<_Tp
, _Lp
>(std::allocator
<_Tp_nc
>(),
1674 std::forward
<_Args
>(__args
)...);
1677 /// std::hash specialization for __shared_ptr.
1678 template<typename _Tp
, _Lock_policy _Lp
>
1679 struct hash
<__shared_ptr
<_Tp
, _Lp
>>
1680 : public __hash_base
<size_t, __shared_ptr
<_Tp
, _Lp
>>
1683 operator()(const __shared_ptr
<_Tp
, _Lp
>& __s
) const noexcept
1684 { return std::hash
<_Tp
*>()(__s
.get()); }
1687 _GLIBCXX_END_NAMESPACE_VERSION
1690 #endif // _SHARED_PTR_BASE_H