30 #ifndef _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 31 #define _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 1 33 #pragma GCC system_header 35 #if __cplusplus <= 201103L 42 namespace std _GLIBCXX_VISIBILITY(default)
44 namespace experimental
46 inline namespace fundamentals_v2
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
49 template<
typename _Tp>
class enable_shared_from_this;
50 _GLIBCXX_END_NAMESPACE_VERSION
54 #define __cpp_lib_experimental_shared_ptr_arrays 201406 56 _GLIBCXX_BEGIN_NAMESPACE_VERSION
69 template <typename _Tp, bool = is_array<_Tp>::value>
70 struct __libfund_v1 {
using type = _Tp; };
74 template<
typename _Tp, _Lock_policy _Lp>
75 class __shared_ptr<__libfund_v1<_Tp, false>, _Lp>
76 :
private __shared_ptr<_Tp, _Lp>
79 template<
typename _Yp,
typename _Res =
void>
81 = enable_if_t<experimental::is_convertible_v<_Yp*, _Tp*>, _Res>;
83 template<
typename _Yp,
typename _Del,
84 typename _Ptr =
typename unique_ptr<_Yp, _Del>::pointer,
86 using _UniqCompatible = enable_if_t<
87 experimental::is_convertible_v<_Yp*, _Tp*>
88 && experimental::is_convertible_v<_Ptr, _Tp*>,
91 using _Base_type = __shared_ptr<_Tp>;
93 _Base_type& _M_get_base() {
return *
this; }
94 const _Base_type& _M_get_base()
const {
return *
this; }
97 using element_type = _Tp;
99 constexpr __shared_ptr() noexcept = default;
101 template<typename _Tp1, typename = _Compatible<_Tp1>>
103 __shared_ptr(_Tp1* __p)
107 template<
typename _Tp1,
typename _Deleter,
typename = _Compatible<_Tp1>>
108 __shared_ptr(_Tp1* __p, _Deleter __d)
109 : _Base_type(__p, __d)
112 template<
typename _Tp1,
typename _Deleter,
typename _Alloc,
113 typename = _Compatible<_Tp1>>
114 __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
115 : _Base_type(__p, __d, __a)
118 template<
typename _Deleter>
119 __shared_ptr(nullptr_t __p, _Deleter __d)
120 : _Base_type(__p, __d)
123 template<
typename _Deleter,
typename _Alloc>
124 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
125 : _Base_type(__p, __d, __a)
128 template<
typename _Tp1>
129 __shared_ptr(
const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r,
130 element_type* __p) noexcept
131 : _Base_type(__r._M_get_base(), __p)
134 __shared_ptr(
const __shared_ptr&) noexcept = default;
135 __shared_ptr(__shared_ptr&&) noexcept = default;
136 __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
137 __shared_ptr& operator=(__shared_ptr&&) noexcept = default;
138 ~__shared_ptr() = default;
140 template<typename _Tp1, typename = _Compatible<_Tp1>>
141 __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
142 : _Base_type(__r._M_get_base())
145 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
146 __shared_ptr(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
147 : _Base_type(
std::move((__r._M_get_base())))
150 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
152 __shared_ptr(
const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r)
153 : _Base_type(__r._M_get_base())
156 template<
typename _Tp1,
typename _Del,
157 typename = _UniqCompatible<_Tp1, _Del>>
158 __shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
159 : _Base_type(
std::move(__r))
162 #if _GLIBCXX_USE_DEPRECATED 164 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
166 : _Base_type(
std::move(__r))
170 constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
175 { __shared_ptr(
nullptr).swap(*
this); }
177 template<
typename _Tp1>
181 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p !=
get());
182 __shared_ptr(__p).swap(*
this);
185 template<
typename _Tp1,
typename _Deleter>
187 reset(_Tp1* __p, _Deleter __d)
188 { __shared_ptr(__p, __d).swap(*
this); }
190 template<
typename _Tp1,
typename _Deleter,
typename _Alloc>
192 reset(_Tp1* __p, _Deleter __d, _Alloc __a)
193 { __shared_ptr(__p, __d, std::move(__a)).swap(*
this); }
195 using _Base_type::operator*;
196 using _Base_type::operator->;
198 template<
typename _Tp1>
199 _Compatible<_Tp1, __shared_ptr&>
200 operator=(
const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
202 _Base_type::operator=(__r._M_get_base());
207 _Compatible<_Tp1, __shared_ptr&>
208 operator=(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
210 _Base_type::operator=(std::move(__r._M_get_base()));
214 template<
typename _Tp1,
typename _Del>
215 _UniqCompatible<_Tp1, _Del, __shared_ptr&>
216 operator=(unique_ptr<_Tp1, _Del>&& __r)
218 _Base_type::operator=(std::move(__r));
222 #if _GLIBCXX_USE_DEPRECATED 223 template<
typename _Tp1>
224 _Compatible<_Tp1, __shared_ptr&>
227 _Base_type::operator=(std::move(__r));
233 swap(__shared_ptr& __other) noexcept
234 { _Base_type::swap(__other); }
236 template<
typename _Tp1>
238 owner_before(__shared_ptr<__libfund_v1<_Tp1>, _Lp>
const& __rhs)
const 239 {
return _Base_type::owner_before(__rhs._M_get_base()); }
241 template<
typename _Tp1>
243 owner_before(__weak_ptr<__libfund_v1<_Tp1>, _Lp>
const& __rhs)
const 244 {
return _Base_type::owner_before(__rhs._M_get_base()); }
246 using _Base_type::operator bool;
247 using _Base_type::get;
248 using _Base_type::unique;
249 using _Base_type::use_count;
265 __shared_ptr(
const __weak_ptr<__libfund_v1<_Tp>, _Lp>& __r,
267 : _Base_type(__r._M_get_base(),
std::nothrow)
271 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __weak_ptr;
272 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __shared_ptr;
275 template<
typename _Del,
typename _Tp1, _Lock_policy _Lp1>
276 friend _Del*
get_deleter(
const __shared_ptr<_Tp1, _Lp1>&) noexcept;
282 template<typename _Yp, typename _Tp>
283 struct __sp_compatible
284 : is_convertible<_Yp*, _Tp*>::type
287 template<
size_t _Nm,
typename _Tp>
288 struct __sp_compatible<_Tp[_Nm], _Tp[]>
292 template<
size_t _Nm,
typename _Tp>
293 struct __sp_compatible<_Tp[_Nm], const _Tp[]>
297 template<
typename _Yp,
typename _Tp>
298 constexpr
bool __sp_compatible_v
299 = __sp_compatible<_Yp, _Tp>::value;
302 template<
typename _Up,
size_t _Nm,
typename _Yp,
typename =
void>
303 struct __sp_is_constructible_arrN
307 template<
typename _Up,
size_t _Nm,
typename _Yp>
308 struct __sp_is_constructible_arrN<_Up, _Nm, _Yp, __void_t<_Yp[_Nm]>>
309 : is_convertible<_Yp(*)[_Nm], _Up(*)[_Nm]>::type
313 template<
typename _Up,
typename _Yp,
typename =
void>
314 struct __sp_is_constructible_arr
318 template<
typename _Up,
typename _Yp>
319 struct __sp_is_constructible_arr<_Up, _Yp, __void_t<_Yp[]>>
320 : is_convertible<_Yp(*)[], _Up(*)[]>::type
324 template<
typename _Tp,
typename _Yp>
325 struct __sp_is_constructible;
328 template<
typename _Up,
size_t _Nm,
typename _Yp>
329 struct __sp_is_constructible<_Up[_Nm], _Yp>
330 : __sp_is_constructible_arrN<_Up, _Nm, _Yp>::type
334 template<
typename _Up,
typename _Yp>
335 struct __sp_is_constructible<_Up[], _Yp>
336 : __sp_is_constructible_arr<_Up, _Yp>::type
340 template<
typename _Tp,
typename _Yp>
341 struct __sp_is_constructible
342 : is_convertible<_Yp*, _Tp*>::type
345 template<
typename _Tp,
typename _Yp>
346 constexpr
bool __sp_is_constructible_v
347 = __sp_is_constructible<_Tp, _Yp>::value;
352 template<
typename _Tp, _Lock_policy _Lp>
353 class __shared_ptr<__libfund_v1<_Tp, true>, _Lp>
354 :
private __shared_ptr<remove_extent_t<_Tp>, _Lp>
357 using element_type = remove_extent_t<_Tp>;
360 struct _Array_deleter
363 operator()(element_type
const *__p)
const 368 template<
typename _Yp>
369 using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
372 template<
typename _Tp1,
typename _Res =
void>
373 using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
376 template<
typename _Tp1,
typename _Del,
377 typename _Ptr =
typename unique_ptr<_Tp1, _Del>::pointer,
378 typename _Res =
void>
379 using _UniqCompatible = enable_if_t<
380 __sp_compatible_v<_Tp1, _Tp>
381 && experimental::is_convertible_v<_Ptr, element_type*>,
384 using _Base_type = __shared_ptr<element_type>;
386 _Base_type& _M_get_base() {
return *
this; }
387 const _Base_type& _M_get_base()
const {
return *
this; }
390 constexpr __shared_ptr() noexcept
394 template<
typename _Tp1,
typename = _SafeConv<_Tp1>>
396 __shared_ptr(_Tp1* __p)
397 : _Base_type(__p, _Array_deleter())
400 template<
typename _Tp1,
typename _Deleter,
typename = _SafeConv<_Tp1>>
401 __shared_ptr(_Tp1* __p, _Deleter __d)
402 : _Base_type(__p, __d)
405 template<
typename _Tp1,
typename _Deleter,
typename _Alloc,
406 typename = _SafeConv<_Tp1>>
407 __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
408 : _Base_type(__p, __d, __a)
411 template<
typename _Deleter>
412 __shared_ptr(nullptr_t __p, _Deleter __d)
413 : _Base_type(__p, __d)
416 template<
typename _Deleter,
typename _Alloc>
417 __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
418 : _Base_type(__p, __d, __a)
421 template<
typename _Tp1>
422 __shared_ptr(
const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r,
423 element_type* __p) noexcept
424 : _Base_type(__r._M_get_base(), __p)
427 __shared_ptr(
const __shared_ptr&) noexcept = default;
428 __shared_ptr(__shared_ptr&&) noexcept = default;
429 __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
430 __shared_ptr& operator=(__shared_ptr&&) noexcept = default;
431 ~__shared_ptr() = default;
433 template<typename _Tp1, typename = _Compatible<_Tp1>>
434 __shared_ptr(const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
435 : _Base_type(__r._M_get_base())
438 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
439 __shared_ptr(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
440 : _Base_type(
std::move((__r._M_get_base())))
443 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
445 __shared_ptr(
const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r)
446 : _Base_type(__r._M_get_base())
449 template<
typename _Tp1,
typename _Del,
450 typename = _UniqCompatible<_Tp1, _Del>>
451 __shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
452 : _Base_type(
std::move(__r))
455 #if _GLIBCXX_USE_DEPRECATED 457 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
458 __shared_ptr(auto_ptr<_Tp1>&& __r)
459 : _Base_type(
std::move(__r))
463 constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { }
468 { __shared_ptr(
nullptr).swap(*
this); }
470 template<
typename _Tp1>
474 _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p !=
get());
475 __shared_ptr(__p, _Array_deleter()).swap(*
this);
478 template<
typename _Tp1,
typename _Deleter>
480 reset(_Tp1* __p, _Deleter __d)
481 { __shared_ptr(__p, __d).swap(*
this); }
483 template<
typename _Tp1,
typename _Deleter,
typename _Alloc>
485 reset(_Tp1* __p, _Deleter __d, _Alloc __a)
486 { __shared_ptr(__p, __d, std::move(__a)).swap(*
this); }
489 operator[](ptrdiff_t i)
const noexcept
491 _GLIBCXX_DEBUG_ASSERT(
get() != 0 && i >= 0);
495 template<
typename _Tp1>
496 _Compatible<_Tp1, __shared_ptr&>
497 operator=(
const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
499 _Base_type::operator=(__r._M_get_base());
504 _Compatible<_Tp1, __shared_ptr&>
505 operator=(__shared_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
507 _Base_type::operator=(std::move(__r._M_get_base()));
511 template<
typename _Tp1,
typename _Del>
512 _UniqCompatible<_Tp1, _Del, __shared_ptr&>
513 operator=(unique_ptr<_Tp1, _Del>&& __r)
515 _Base_type::operator=(std::move(__r));
519 #if _GLIBCXX_USE_DEPRECATED 520 template<
typename _Tp1>
521 _Compatible<_Tp1, __shared_ptr&>
522 operator=(auto_ptr<_Tp1>&& __r)
524 _Base_type::operator=(std::move(__r));
530 swap(__shared_ptr& __other) noexcept
531 { _Base_type::swap(__other); }
533 template<
typename _Tp1>
535 owner_before(__shared_ptr<__libfund_v1<_Tp1>, _Lp>
const& __rhs)
const 536 {
return _Base_type::owner_before(__rhs._M_get_base()); }
538 template<
typename _Tp1>
540 owner_before(__weak_ptr<__libfund_v1<_Tp1>, _Lp>
const& __rhs)
const 541 {
return _Base_type::owner_before(__rhs._M_get_base()); }
543 using _Base_type::operator bool;
544 using _Base_type::get;
545 using _Base_type::unique;
546 using _Base_type::use_count;
562 __shared_ptr(
const __weak_ptr<__libfund_v1<_Tp>, _Lp>& __r,
564 : _Base_type(__r._M_get_base(),
std::nothrow)
568 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __weak_ptr;
569 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __shared_ptr;
572 template<
typename _Del,
typename _Tp1, _Lock_policy _Lp1>
573 friend _Del*
get_deleter(
const __shared_ptr<_Tp1, _Lp1>&) noexcept;
577 template<typename _Tp, _Lock_policy _Lp>
578 class __weak_ptr<__libfund_v1<_Tp>, _Lp>
579 : __weak_ptr<remove_extent_t<_Tp>, _Lp>
581 template<
typename _Tp1,
typename _Res =
void>
583 = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
585 using _Base_type = __weak_ptr<remove_extent_t<_Tp>>;
587 _Base_type& _M_get_base() {
return *
this; }
588 const _Base_type& _M_get_base()
const {
return *
this; }
591 using element_type = remove_extent_t<_Tp>;
593 constexpr __weak_ptr() noexcept
597 __weak_ptr(
const __weak_ptr&) noexcept = default;
599 ~__weak_ptr() = default;
601 template<typename _Tp1, typename = _Compatible<_Tp1>>
602 __weak_ptr(const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
603 : _Base_type(__r._M_get_base())
606 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
607 __weak_ptr(
const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
608 : _Base_type(__r._M_get_base())
611 __weak_ptr(__weak_ptr&& __r) noexcept
612 : _Base_type(
std::move(__r))
615 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
616 __weak_ptr(__weak_ptr<__libfund_v1<_Tp1>, _Lp>&& __r) noexcept
617 : _Base_type(
std::move(__r._M_get_base()))
621 operator=(
const __weak_ptr& __r) noexcept =
default;
623 template<
typename _Tp1>
624 _Compatible<_Tp1, __weak_ptr&>
625 operator=(
const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __r) noexcept
627 this->_Base_type::operator=(__r._M_get_base());
631 template<
typename _Tp1>
632 _Compatible<_Tp1, __weak_ptr&>
633 operator=(
const __shared_ptr<_Tp1, _Lp>& __r) noexcept
635 this->_Base_type::operator=(__r._M_get_base());
640 operator=(__weak_ptr&& __r) noexcept
642 this->_Base_type::operator=(std::move(__r));
646 template<
typename _Tp1>
647 _Compatible<_Tp1, __weak_ptr&>
648 operator=(__weak_ptr<_Tp1, _Lp>&& __r) noexcept
650 this->_Base_type::operator=(std::move(__r._M_get_base()));
655 swap(__weak_ptr& __other) noexcept
656 { this->_Base_type::swap(__other); }
658 template<
typename _Tp1>
660 owner_before(
const __shared_ptr<__libfund_v1<_Tp1>, _Lp>& __rhs)
const 661 {
return _Base_type::owner_before(__rhs._M_get_base()); }
663 template<
typename _Tp1>
665 owner_before(
const __weak_ptr<__libfund_v1<_Tp1>, _Lp>& __rhs)
const 666 {
return _Base_type::owner_before(__rhs._M_get_base()); }
668 __shared_ptr<__libfund_v1<_Tp>, _Lp>
669 lock() const noexcept
670 {
return __shared_ptr<__libfund_v1<_Tp>, _Lp>(*
this, std::nothrow); }
672 using _Base_type::use_count;
673 using _Base_type::expired;
674 using _Base_type::reset;
679 _M_assign(element_type* __ptr,
680 const __shared_count<_Lp>& __refcount) noexcept
681 { this->_Base_type::_M_assign(__ptr, __refcount); }
683 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __shared_ptr;
684 template<
typename _Tp1, _Lock_policy _Lp1>
friend class __weak_ptr;
685 friend class __enable_shared_from_this<_Tp, _Lp>;
686 friend class experimental::enable_shared_from_this<_Tp>;
687 friend class enable_shared_from_this<_Tp>;
690 _GLIBCXX_END_NAMESPACE_VERSION
692 namespace experimental
694 inline namespace fundamentals_v2
696 _GLIBCXX_BEGIN_NAMESPACE_VERSION
700 template<
typename _Tp>
class shared_ptr;
701 template<
typename _Tp>
class weak_ptr;
703 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
704 using __shared_ptr = std::__shared_ptr<__libfund_v1<_Tp>, _Lp>;
706 template<
typename _Tp, _Lock_policy _Lp = __default_lock_policy>
707 using __weak_ptr = std::__weak_ptr<__libfund_v1<_Tp>, _Lp>;
709 template<
typename _Tp>
710 class shared_ptr :
public __shared_ptr<_Tp>
712 using _Base_type = __shared_ptr<_Tp>;
715 using element_type =
typename _Base_type::element_type;
719 template<
typename _Yp>
720 using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
722 template<
typename _Tp1,
typename _Res =
void>
724 = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
726 template<
typename _Tp1,
typename _Del,
727 typename _Ptr =
typename unique_ptr<_Tp1, _Del>::pointer,
728 typename _Res =
void>
729 using _UniqCompatible = enable_if_t<
730 __sp_compatible_v<_Tp1, _Tp>
731 && experimental::is_convertible_v<_Ptr, element_type*>,
737 constexpr shared_ptr() noexcept = default;
739 template<typename _Tp1, typename = _SafeConv<_Tp1>>
741 shared_ptr(_Tp1* __p) : _Base_type(__p)
742 { _M_enable_shared_from_this_with(__p); }
744 template<
typename _Tp1,
typename _Deleter,
typename = _SafeConv<_Tp1>>
745 shared_ptr(_Tp1* __p, _Deleter __d)
746 : _Base_type(__p, __d)
747 { _M_enable_shared_from_this_with(__p); }
749 template<
typename _Tp1,
typename _Deleter,
typename _Alloc,
750 typename = _SafeConv<_Tp1>>
751 shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
752 : _Base_type(__p, __d, __a)
753 { _M_enable_shared_from_this_with(__p); }
755 template<
typename _Deleter>
756 shared_ptr(nullptr_t __p, _Deleter __d)
757 : _Base_type(__p, __d) { }
759 template<
typename _Deleter,
typename _Alloc>
760 shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
761 : _Base_type(__p, __d, __a) { }
763 template<
typename _Tp1>
764 shared_ptr(
const shared_ptr<_Tp1>& __r, element_type* __p) noexcept
765 : _Base_type(__r, __p) { }
767 shared_ptr(
const shared_ptr& __r) noexcept
768 : _Base_type(__r) { }
770 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
771 shared_ptr(
const shared_ptr<_Tp1>& __r) noexcept
772 : _Base_type(__r) { }
774 shared_ptr(shared_ptr&& __r) noexcept
775 : _Base_type(
std::move(__r)) { }
777 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
778 shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
779 : _Base_type(
std::move(__r)) { }
781 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
783 shared_ptr(
const weak_ptr<_Tp1>& __r)
784 : _Base_type(__r) { }
786 #if _GLIBCXX_USE_DEPRECATED 787 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
789 : _Base_type(
std::move(__r))
790 { _M_enable_shared_from_this_with(static_cast<_Tp1*>(this->
get())); }
793 template<
typename _Tp1,
typename _Del,
794 typename = _UniqCompatible<_Tp1, _Del>>
795 shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
796 : _Base_type(
std::move(__r))
800 using __elem_t =
typename unique_ptr<_Tp1, _Del>::element_type;
801 _M_enable_shared_from_this_with(static_cast<__elem_t*>(this->
get()));
804 constexpr shared_ptr(nullptr_t __p)
805 : _Base_type(__p) { }
808 ~shared_ptr() =
default;
811 shared_ptr& operator=(
const shared_ptr&) noexcept = default;
813 template <typename _Tp1>
814 _Compatible<_Tp1, shared_ptr&>
815 operator=(const shared_ptr<_Tp1>& __r) noexcept
817 _Base_type::operator=(__r);
822 operator=(shared_ptr&& __r) noexcept
824 _Base_type::operator=(std::move(__r));
828 template <
typename _Tp1>
829 _Compatible<_Tp1, shared_ptr&>
830 operator=(shared_ptr<_Tp1>&& __r) noexcept
832 _Base_type::operator=(std::move(__r));
836 #if _GLIBCXX_USE_DEPRECATED 837 template<
typename _Tp1>
838 _Compatible<_Tp1, shared_ptr&>
841 __shared_ptr<_Tp>::operator=(std::move(__r));
846 template <
typename _Tp1,
typename _Del>
847 _UniqCompatible<_Tp1, _Del, shared_ptr&>
848 operator=(unique_ptr<_Tp1, _Del>&& __r)
850 _Base_type::operator=(std::move(__r));
860 template<
typename _Alloc,
typename... _Args>
861 shared_ptr(_Sp_make_shared_tag __tag,
const _Alloc& __a,
863 : _Base_type(__tag, __a,
std::
forward<_Args>(__args)...)
864 { _M_enable_shared_from_this_with(this->
get()); }
866 template<
typename _Tp1,
typename _Alloc,
typename... _Args>
867 friend shared_ptr<_Tp1>
870 shared_ptr(
const weak_ptr<_Tp>& __r, std::nothrow_t)
871 : _Base_type(__r,
std::nothrow) { }
873 friend class weak_ptr<_Tp>;
875 template<
typename _Yp>
876 using __esft_base_t =
877 decltype(__expt_enable_shared_from_this_base(std::declval<_Yp*>()));
880 template<
typename _Yp,
typename =
void>
881 struct __has_esft_base
884 template<
typename _Yp>
885 struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
886 : __bool_constant<!is_array_v<_Tp>> { };
888 template<
typename _Yp>
889 typename enable_if<__has_esft_base<_Yp>::value>::type
890 _M_enable_shared_from_this_with(
const _Yp* __p) noexcept
892 if (
auto __base = __expt_enable_shared_from_this_base(__p))
895 = shared_ptr<_Yp>(*
this,
const_cast<_Yp*
>(__p));
899 template<
typename _Yp>
900 typename enable_if<!__has_esft_base<_Yp>::value>::type
901 _M_enable_shared_from_this_with(
const _Yp*) noexcept
906 template<
typename _Tp1,
typename _Tp2>
907 bool operator==(
const shared_ptr<_Tp1>& __a,
908 const shared_ptr<_Tp2>& __b) noexcept
909 {
return __a.get() == __b.get(); }
911 template<
typename _Tp>
913 operator==(
const shared_ptr<_Tp>& __a, nullptr_t) noexcept
916 template<
typename _Tp>
918 operator==(nullptr_t,
const shared_ptr<_Tp>& __a) noexcept
921 template<
typename _Tp1,
typename _Tp2>
923 operator!=(
const shared_ptr<_Tp1>& __a,
924 const shared_ptr<_Tp2>& __b) noexcept
925 {
return __a.get() != __b.get(); }
927 template<
typename _Tp>
929 operator!=(
const shared_ptr<_Tp>& __a, nullptr_t) noexcept
930 {
return (
bool)__a; }
932 template<
typename _Tp>
934 operator!=(nullptr_t,
const shared_ptr<_Tp>& __a) noexcept
935 {
return (
bool)__a; }
937 template<
typename _Tp1,
typename _Tp2>
939 operator<(const shared_ptr<_Tp1>& __a,
940 const shared_ptr<_Tp2>& __b) noexcept
942 using __elem_t1 =
typename shared_ptr<_Tp1>::element_type;
943 using __elem_t2 =
typename shared_ptr<_Tp2>::element_type;
944 using _CT = common_type_t<__elem_t1*, __elem_t2*>;
948 template<
typename _Tp>
950 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
952 using __elem_t =
typename shared_ptr<_Tp>::element_type;
956 template<
typename _Tp>
958 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
960 using __elem_t =
typename shared_ptr<_Tp>::element_type;
964 template<
typename _Tp1,
typename _Tp2>
966 operator<=(const shared_ptr<_Tp1>& __a,
967 const shared_ptr<_Tp2>& __b) noexcept
968 {
return !(__b < __a); }
970 template<
typename _Tp>
972 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
973 {
return !(
nullptr < __a); }
975 template<
typename _Tp>
977 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
978 {
return !(__a <
nullptr); }
980 template<
typename _Tp1,
typename _Tp2>
982 operator>(
const shared_ptr<_Tp1>& __a,
983 const shared_ptr<_Tp2>& __b) noexcept
984 {
return (__b < __a); }
986 template<
typename _Tp>
988 operator>(
const shared_ptr<_Tp>& __a, nullptr_t) noexcept
990 using __elem_t =
typename shared_ptr<_Tp>::element_type;
994 template<
typename _Tp>
996 operator>(nullptr_t,
const shared_ptr<_Tp>& __a) noexcept
998 using __elem_t =
typename shared_ptr<_Tp>::element_type;
1002 template<
typename _Tp1,
typename _Tp2>
1004 operator>=(
const shared_ptr<_Tp1>& __a,
1005 const shared_ptr<_Tp2>& __b) noexcept
1006 {
return !(__a < __b); }
1008 template<
typename _Tp>
1010 operator>=(
const shared_ptr<_Tp>& __a, nullptr_t) noexcept
1011 {
return !(__a <
nullptr); }
1013 template<
typename _Tp>
1015 operator>=(nullptr_t,
const shared_ptr<_Tp>& __a) noexcept
1016 {
return !(
nullptr < __a); }
1019 template<
typename _Tp>
1021 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
1025 template<
typename _Tp,
typename _Tp1>
1026 inline shared_ptr<_Tp>
1027 static_pointer_cast(
const shared_ptr<_Tp1>& __r) noexcept
1029 using __elem_t =
typename shared_ptr<_Tp>::element_type;
1030 return shared_ptr<_Tp>(__r,
static_cast<__elem_t*
>(__r.get()));
1033 template<
typename _Tp,
typename _Tp1>
1034 inline shared_ptr<_Tp>
1035 dynamic_pointer_cast(
const shared_ptr<_Tp1>& __r) noexcept
1037 using __elem_t =
typename shared_ptr<_Tp>::element_type;
1038 if (_Tp* __p = dynamic_cast<__elem_t*>(__r.get()))
1039 return shared_ptr<_Tp>(__r, __p);
1040 return shared_ptr<_Tp>();
1043 template<
typename _Tp,
typename _Tp1>
1044 inline shared_ptr<_Tp>
1045 const_pointer_cast(
const shared_ptr<_Tp1>& __r) noexcept
1047 using __elem_t =
typename shared_ptr<_Tp>::element_type;
1048 return shared_ptr<_Tp>(__r,
const_cast<__elem_t*
>(__r.get()));
1051 template<
typename _Tp,
typename _Tp1>
1052 inline shared_ptr<_Tp>
1053 reinterpret_pointer_cast(
const shared_ptr<_Tp1>& __r) noexcept
1055 using __elem_t =
typename shared_ptr<_Tp>::element_type;
1056 return shared_ptr<_Tp>(__r,
reinterpret_cast<__elem_t*
>(__r.get()));
1060 template<
typename _Tp>
1061 class weak_ptr :
public __weak_ptr<_Tp>
1063 template<
typename _Tp1,
typename _Res =
void>
1064 using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
1066 using _Base_type = __weak_ptr<_Tp>;
1069 constexpr weak_ptr() noexcept = default;
1071 template<typename _Tp1, typename = _Compatible<_Tp1>>
1072 weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
1073 : _Base_type(__r) { }
1075 weak_ptr(
const weak_ptr&) noexcept = default;
1077 template<typename _Tp1, typename = _Compatible<_Tp1>>
1078 weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
1079 : _Base_type(__r) { }
1081 weak_ptr(weak_ptr&&) noexcept = default;
1083 template<typename _Tp1, typename = _Compatible<_Tp1>>
1084 weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
1085 : _Base_type(
std::move(__r)) { }
1088 operator=(
const weak_ptr& __r) noexcept =
default;
1090 template<
typename _Tp1>
1091 _Compatible<_Tp1, weak_ptr&>
1092 operator=(
const weak_ptr<_Tp1>& __r) noexcept
1094 this->_Base_type::operator=(__r);
1098 template<
typename _Tp1>
1099 _Compatible<_Tp1, weak_ptr&>
1100 operator=(
const shared_ptr<_Tp1>& __r) noexcept
1102 this->_Base_type::operator=(__r);
1107 operator=(weak_ptr&& __r) noexcept = default;
1109 template<typename _Tp1>
1110 _Compatible<_Tp1, weak_ptr&>
1111 operator=(weak_ptr<_Tp1>&& __r) noexcept
1113 this->_Base_type::operator=(std::move(__r));
1118 lock() const noexcept
1119 {
return shared_ptr<_Tp>(*
this, std::nothrow); }
1121 friend class enable_shared_from_this<_Tp>;
1125 template<
typename _Tp>
1127 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
1131 template<
typename _Del,
typename _Tp, _Lock_policy _Lp>
1134 {
return std::get_deleter<_Del>(__p); }
1137 template<
typename _Ch,
typename _Tr,
typename _Tp, _Lock_policy _Lp>
1139 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
1140 const __shared_ptr<_Tp, _Lp>& __p)
1147 template<
typename _Tp =
void>
class owner_less;
1150 template<
typename _Tp>
1151 struct owner_less<shared_ptr<_Tp>>
1152 :
public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
1156 template<
typename _Tp>
1157 struct owner_less<weak_ptr<_Tp>>
1158 :
public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
1162 class owner_less<void>
1164 template<
typename _Tp,
typename _Up>
1166 operator()(shared_ptr<_Tp>
const& __lhs,
1167 shared_ptr<_Up>
const& __rhs)
const 1168 {
return __lhs.owner_before(__rhs); }
1170 template<
typename _Tp,
typename _Up>
1172 operator()(shared_ptr<_Tp>
const& __lhs,
1173 weak_ptr<_Up>
const& __rhs)
const 1174 {
return __lhs.owner_before(__rhs); }
1176 template<
typename _Tp,
typename _Up>
1178 operator()(weak_ptr<_Tp>
const& __lhs,
1179 shared_ptr<_Up>
const& __rhs)
const 1180 {
return __lhs.owner_before(__rhs); }
1182 template<
typename _Tp,
typename _Up>
1184 operator()(weak_ptr<_Tp>
const& __lhs,
1185 weak_ptr<_Up>
const& __rhs)
const 1186 {
return __lhs.owner_before(__rhs); }
1188 typedef void is_transparent;
1192 template<
typename _Tp>
1194 atomic_is_lock_free(
const shared_ptr<_Tp>* __p)
1195 {
return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }
1197 template<
typename _Tp>
1198 shared_ptr<_Tp> atomic_load(
const shared_ptr<_Tp>* __p)
1199 {
return std::atomic_load<_Tp>(__p); }
1201 template<
typename _Tp>
1203 atomic_load_explicit(
const shared_ptr<_Tp>* __p,
memory_order __mo)
1204 {
return std::atomic_load_explicit<_Tp>(__p, __mo); }
1206 template<
typename _Tp>
1207 void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
1208 {
return std::atomic_store<_Tp>(__p, __r); }
1210 template<
typename _Tp>
1212 atomic_store_explicit(
const shared_ptr<_Tp>* __p,
1213 shared_ptr<_Tp> __r,
1215 {
return std::atomic_store_explicit<_Tp>(__p, __r, __mo); }
1217 template<
typename _Tp>
1218 void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
1219 {
return std::atomic_exchange<_Tp>(__p, __r); }
1221 template<
typename _Tp>
1223 atomic_exchange_explicit(
const shared_ptr<_Tp>* __p,
1224 shared_ptr<_Tp> __r,
1226 {
return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); }
1228 template<
typename _Tp>
1229 bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p,
1230 shared_ptr<_Tp>* __v,
1231 shared_ptr<_Tp> __w)
1232 {
return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); }
1234 template<
typename _Tp>
1235 bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p,
1236 shared_ptr<_Tp>* __v,
1237 shared_ptr<_Tp> __w)
1238 {
return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); }
1240 template<
typename _Tp>
1241 bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
1242 shared_ptr<_Tp>* __v,
1243 shared_ptr<_Tp> __w,
1246 {
return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w,
1250 template<
typename _Tp>
1251 bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
1252 shared_ptr<_Tp>* __v,
1253 shared_ptr<_Tp> __w,
1256 {
return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w,
1261 template<
typename _Tp>
1262 class enable_shared_from_this
1265 constexpr enable_shared_from_this() noexcept { }
1267 enable_shared_from_this(
const enable_shared_from_this&) noexcept { }
1269 enable_shared_from_this&
1270 operator=(
const enable_shared_from_this&) noexcept
1273 ~enable_shared_from_this() { }
1278 {
return shared_ptr<_Tp>(this->_M_weak_this); }
1280 shared_ptr<const _Tp>
1281 shared_from_this()
const 1282 {
return shared_ptr<const _Tp>(this->_M_weak_this); }
1285 weak_from_this() noexcept
1286 {
return _M_weak_this; }
1289 weak_from_this()
const noexcept
1290 {
return _M_weak_this; }
1293 template<
typename _Tp1>
1295 _M_weak_assign(_Tp1* __p,
const __shared_count<>& __n)
const noexcept
1296 { _M_weak_this._M_assign(__p, __n); }
1299 friend const enable_shared_from_this*
1300 __expt_enable_shared_from_this_base(
const enable_shared_from_this* __p)
1304 friend class shared_ptr;
1306 mutable weak_ptr<_Tp> _M_weak_this;
1309 _GLIBCXX_END_NAMESPACE_VERSION
1313 _GLIBCXX_BEGIN_NAMESPACE_VERSION
1316 template<
typename _Tp>
1317 struct hash<experimental::shared_ptr<_Tp>>
1318 :
public __hash_base<size_t, experimental::shared_ptr<_Tp>>
1321 operator()(
const experimental::shared_ptr<_Tp>& __s)
const noexcept
1325 _GLIBCXX_END_NAMESPACE_VERSION
1328 #endif // __cplusplus <= 201103L 1330 #endif // _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
Template class basic_ostream.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
shared_ptr< _Tp > allocate_shared(const _Alloc &__a, _Args &&...__args)
Create an object that is owned by a shared_ptr.
Partial specializations for pointer types.
memory_order
Enumeration for memory_order.
A simple smart pointer providing strict ownership semantics.
One of the comparison functors.
void lock(_L1 &__l1, _L2 &__l2, _L3 &...__l3)
Generic lock.
_Del * get_deleter(const __shared_ptr< _Tp, _Lp > &__p) noexcept
20.7.2.2.10 shared_ptr get_deleter
ISO C++ entities toplevel namespace is std.
integral_constant< bool, true > true_type
The type used as a compile-time boolean with true value.
Primary class template hash.