30#ifndef _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H
31#define _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 1
34#pragma GCC system_header
37#if __cplusplus >= 201402L
42namespace std _GLIBCXX_VISIBILITY(default)
44_GLIBCXX_BEGIN_NAMESPACE_VERSION
48inline namespace fundamentals_v2
52 template<
typename _Tp>
class shared_ptr;
53 template<
typename _Tp>
class weak_ptr;
54 template<
typename _Tp>
class enable_shared_from_this;
56 template<
typename _Yp,
typename _Tp>
57 constexpr bool __sp_compatible_v
58 = std::__sp_compatible_with<_Yp*, _Tp*>::value;
60 template<
typename _Tp,
typename _Yp>
61 constexpr bool __sp_is_constructible_v
62 = std::__sp_is_constructible<_Tp, _Yp>::value;
64 template<
typename _Tp>
65 class shared_ptr :
public __shared_ptr<_Tp>
67 using _Base_type = __shared_ptr<_Tp>;
70 using element_type =
typename _Base_type::element_type;
74 template<
typename _Yp>
77 template<
typename _Tp1,
typename _Res =
void>
81 template<
typename _Tp1,
typename _Del,
82 typename _Ptr =
typename unique_ptr<_Tp1, _Del>::pointer,
85 __sp_compatible_v<_Tp1, _Tp>
86 && experimental::is_convertible_v<_Ptr, element_type*>,
92 constexpr shared_ptr() noexcept = default;
94 template<typename _Tp1, typename = _SafeConv<_Tp1>>
96 shared_ptr(_Tp1* __p) : _Base_type(__p)
97 { _M_enable_shared_from_this_with(__p); }
99 template<
typename _Tp1,
typename _Deleter,
typename = _SafeConv<_Tp1>>
100 shared_ptr(_Tp1* __p, _Deleter __d)
101 : _Base_type(__p, __d)
102 { _M_enable_shared_from_this_with(__p); }
104 template<
typename _Tp1,
typename _Deleter,
typename _Alloc,
105 typename = _SafeConv<_Tp1>>
106 shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
107 : _Base_type(__p, __d, __a)
108 { _M_enable_shared_from_this_with(__p); }
110 template<
typename _Deleter>
111 shared_ptr(nullptr_t __p, _Deleter __d)
112 : _Base_type(__p, __d) { }
114 template<
typename _Deleter,
typename _Alloc>
115 shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
116 : _Base_type(__p, __d, __a) { }
118 template<
typename _Tp1>
119 shared_ptr(
const shared_ptr<_Tp1>& __r, element_type* __p) noexcept
120 : _Base_type(__r, __p) { }
122 shared_ptr(
const shared_ptr& __r) noexcept
123 : _Base_type(__r) { }
125 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
126 shared_ptr(
const shared_ptr<_Tp1>& __r) noexcept
127 : _Base_type(__r) { }
129 shared_ptr(shared_ptr&& __r) noexcept
132 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
133 shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
136 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
138 shared_ptr(
const weak_ptr<_Tp1>& __r)
139 : _Base_type(__r) { }
141#if _GLIBCXX_USE_DEPRECATED
142#pragma GCC diagnostic push
143#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
144 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
145 shared_ptr(std::auto_ptr<_Tp1>&& __r)
146 : _Base_type(std::
move(__r))
147 { _M_enable_shared_from_this_with(
static_cast<_Tp1*
>(this->get())); }
148#pragma GCC diagnostic pop
151 template<
typename _Tp1,
typename _Del,
152 typename = _UniqCompatible<_Tp1, _Del>>
153 shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
154 : _Base_type(std::
move(__r))
158 using __elem_t =
typename unique_ptr<_Tp1, _Del>::element_type;
159 _M_enable_shared_from_this_with(
static_cast<__elem_t*
>(this->get()));
162 constexpr shared_ptr(nullptr_t __p)
163 : _Base_type(__p) { }
166 ~shared_ptr() =
default;
169 shared_ptr& operator=(
const shared_ptr&)
noexcept =
default;
171 template <
typename _Tp1>
172 _Compatible<_Tp1, shared_ptr&>
173 operator=(
const shared_ptr<_Tp1>& __r)
noexcept
175 _Base_type::operator=(__r);
180 operator=(shared_ptr&& __r)
noexcept
186 template <
typename _Tp1>
187 _Compatible<_Tp1, shared_ptr&>
188 operator=(shared_ptr<_Tp1>&& __r)
noexcept
194#if _GLIBCXX_USE_DEPRECATED
195#pragma GCC diagnostic push
196#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
197 template<
typename _Tp1>
198 _Compatible<_Tp1, shared_ptr&>
199 operator=(std::auto_ptr<_Tp1>&& __r)
201 __shared_ptr<_Tp>::operator=(
std::move(__r));
204#pragma GCC diagnostic pop
207 template <
typename _Tp1,
typename _Del>
208 _UniqCompatible<_Tp1, _Del, shared_ptr&>
209 operator=(unique_ptr<_Tp1, _Del>&& __r)
221 template<
typename _Alloc,
typename... _Args>
222 shared_ptr(_Sp_make_shared_tag __tag,
const _Alloc& __a,
224 : _Base_type(__tag, __a, std::
forward<_Args>(__args)...)
225 { _M_enable_shared_from_this_with(this->get()); }
227 template<
typename _Tp1,
typename _Alloc,
typename... _Args>
228 friend shared_ptr<_Tp1>
229 allocate_shared(
const _Alloc& __a, _Args&&... __args);
231 shared_ptr(
const weak_ptr<_Tp>& __r, std::nothrow_t)
232 : _Base_type(__r, std::nothrow) { }
234 friend class weak_ptr<_Tp>;
236 template<
typename _Yp>
237 using __esft_base_t =
241 template<
typename _Yp,
typename =
void>
242 struct __has_esft_base
245 template<
typename _Yp>
246 struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
247 : __bool_constant<!is_array_v<_Tp>> { };
249 template<
typename _Yp>
250 typename enable_if<__has_esft_base<_Yp>::value>::type
251 _M_enable_shared_from_this_with(
const _Yp* __p)
noexcept
253 if (
auto __base = __expt_enable_shared_from_this_base(__p))
256 = shared_ptr<_Yp>(*
this,
const_cast<_Yp*
>(__p));
260 template<
typename _Yp>
261 typename enable_if<!__has_esft_base<_Yp>::value>::type
262 _M_enable_shared_from_this_with(
const _Yp*)
noexcept
267 template<
typename _Tp1,
typename _Tp2>
268 bool operator==(
const shared_ptr<_Tp1>& __a,
269 const shared_ptr<_Tp2>& __b)
noexcept
270 {
return __a.get() == __b.get(); }
272 template<
typename _Tp>
274 operator==(
const shared_ptr<_Tp>& __a, nullptr_t)
noexcept
277 template<
typename _Tp>
279 operator==(nullptr_t,
const shared_ptr<_Tp>& __a)
noexcept
282 template<
typename _Tp1,
typename _Tp2>
284 operator!=(
const shared_ptr<_Tp1>& __a,
285 const shared_ptr<_Tp2>& __b)
noexcept
286 {
return __a.get() != __b.get(); }
288 template<
typename _Tp>
290 operator!=(
const shared_ptr<_Tp>& __a, nullptr_t)
noexcept
291 {
return (
bool)__a; }
293 template<
typename _Tp>
295 operator!=(nullptr_t,
const shared_ptr<_Tp>& __a)
noexcept
296 {
return (
bool)__a; }
298 template<
typename _Tp1,
typename _Tp2>
300 operator<(
const shared_ptr<_Tp1>& __a,
301 const shared_ptr<_Tp2>& __b)
noexcept
303 using __elem_t1 =
typename shared_ptr<_Tp1>::element_type;
304 using __elem_t2 =
typename shared_ptr<_Tp2>::element_type;
306 return std::less<_CT>()(__a.get(), __b.get());
309 template<
typename _Tp>
311 operator<(
const shared_ptr<_Tp>& __a, nullptr_t)
noexcept
313 using __elem_t =
typename shared_ptr<_Tp>::element_type;
314 return std::less<__elem_t*>()(__a.get(),
nullptr);
317 template<
typename _Tp>
319 operator<(nullptr_t,
const shared_ptr<_Tp>& __a)
noexcept
321 using __elem_t =
typename shared_ptr<_Tp>::element_type;
322 return std::less<__elem_t*>()(
nullptr, __a.get());
325 template<
typename _Tp1,
typename _Tp2>
327 operator<=(
const shared_ptr<_Tp1>& __a,
328 const shared_ptr<_Tp2>& __b)
noexcept
329 {
return !(__b < __a); }
331 template<
typename _Tp>
333 operator<=(
const shared_ptr<_Tp>& __a, nullptr_t)
noexcept
334 {
return !(
nullptr < __a); }
336 template<
typename _Tp>
338 operator<=(nullptr_t,
const shared_ptr<_Tp>& __a)
noexcept
339 {
return !(__a <
nullptr); }
341 template<
typename _Tp1,
typename _Tp2>
343 operator>(
const shared_ptr<_Tp1>& __a,
344 const shared_ptr<_Tp2>& __b)
noexcept
345 {
return (__b < __a); }
347 template<
typename _Tp>
349 operator>(
const shared_ptr<_Tp>& __a, nullptr_t)
noexcept
351 using __elem_t =
typename shared_ptr<_Tp>::element_type;
352 return std::less<__elem_t*>()(
nullptr, __a.get());
355 template<
typename _Tp>
357 operator>(nullptr_t,
const shared_ptr<_Tp>& __a)
noexcept
359 using __elem_t =
typename shared_ptr<_Tp>::element_type;
360 return std::less<__elem_t*>()(__a.get(),
nullptr);
363 template<
typename _Tp1,
typename _Tp2>
365 operator>=(
const shared_ptr<_Tp1>& __a,
366 const shared_ptr<_Tp2>& __b)
noexcept
367 {
return !(__a < __b); }
369 template<
typename _Tp>
371 operator>=(
const shared_ptr<_Tp>& __a, nullptr_t)
noexcept
372 {
return !(__a <
nullptr); }
374 template<
typename _Tp>
376 operator>=(nullptr_t,
const shared_ptr<_Tp>& __a)
noexcept
377 {
return !(
nullptr < __a); }
380 template<
typename _Tp>
382 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b)
noexcept
386 template<
typename _Tp,
typename _Tp1>
387 inline shared_ptr<_Tp>
388 static_pointer_cast(
const shared_ptr<_Tp1>& __r)
noexcept
390 using __elem_t =
typename shared_ptr<_Tp>::element_type;
391 return shared_ptr<_Tp>(__r,
static_cast<__elem_t*
>(__r.get()));
394 template<
typename _Tp,
typename _Tp1>
395 inline shared_ptr<_Tp>
396 dynamic_pointer_cast(
const shared_ptr<_Tp1>& __r)
noexcept
398 using __elem_t =
typename shared_ptr<_Tp>::element_type;
399 if (_Tp* __p =
dynamic_cast<__elem_t*
>(__r.get()))
400 return shared_ptr<_Tp>(__r, __p);
401 return shared_ptr<_Tp>();
404 template<
typename _Tp,
typename _Tp1>
405 inline shared_ptr<_Tp>
406 const_pointer_cast(
const shared_ptr<_Tp1>& __r)
noexcept
408 using __elem_t =
typename shared_ptr<_Tp>::element_type;
409 return shared_ptr<_Tp>(__r,
const_cast<__elem_t*
>(__r.get()));
412 template<
typename _Tp,
typename _Tp1>
413 inline shared_ptr<_Tp>
414 reinterpret_pointer_cast(
const shared_ptr<_Tp1>& __r)
noexcept
416 using __elem_t =
typename shared_ptr<_Tp>::element_type;
417 return shared_ptr<_Tp>(__r,
reinterpret_cast<__elem_t*
>(__r.get()));
421 template<
typename _Tp>
422 class weak_ptr :
public __weak_ptr<_Tp>
424 template<
typename _Tp1,
typename _Res =
void>
427 using _Base_type = __weak_ptr<_Tp>;
430 constexpr weak_ptr() noexcept = default;
432 template<typename _Tp1, typename = _Compatible<_Tp1>>
433 weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
434 : _Base_type(__r) { }
436 weak_ptr(
const weak_ptr&)
noexcept =
default;
438 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
439 weak_ptr(
const weak_ptr<_Tp1>& __r) noexcept
440 : _Base_type(__r) { }
442 weak_ptr(weak_ptr&&) noexcept = default;
444 template<typename _Tp1, typename = _Compatible<_Tp1>>
445 weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
446 : _Base_type(std::
move(__r)) { }
449 operator=(
const weak_ptr& __r)
noexcept =
default;
451 template<
typename _Tp1>
452 _Compatible<_Tp1, weak_ptr&>
453 operator=(
const weak_ptr<_Tp1>& __r)
noexcept
455 this->_Base_type::operator=(__r);
459 template<
typename _Tp1>
460 _Compatible<_Tp1, weak_ptr&>
461 operator=(
const shared_ptr<_Tp1>& __r)
noexcept
463 this->_Base_type::operator=(__r);
468 operator=(weak_ptr&& __r)
noexcept =
default;
470 template<
typename _Tp1>
471 _Compatible<_Tp1, weak_ptr&>
472 operator=(weak_ptr<_Tp1>&& __r)
noexcept
474 this->_Base_type::operator=(
std::move(__r));
479 lock() const noexcept
480 {
return shared_ptr<_Tp>(*
this, std::nothrow); }
482 friend class enable_shared_from_this<_Tp>;
486 template<
typename _Tp>
488 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b)
noexcept
492 template<
typename _Del,
typename _Tp>
495 {
return std::get_deleter<_Del>(__p); }
498 template<
typename _Ch,
typename _Tr,
typename _Tp>
507 template<
typename _Tp =
void>
class owner_less;
510 template<
typename _Tp>
511 struct owner_less<shared_ptr<_Tp>>
512 :
public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
516 template<
typename _Tp>
517 struct owner_less<weak_ptr<_Tp>>
518 :
public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
522 class owner_less<void>
524 template<
typename _Tp,
typename _Up>
526 operator()(shared_ptr<_Tp>
const& __lhs,
527 shared_ptr<_Up>
const& __rhs)
const
528 {
return __lhs.owner_before(__rhs); }
530 template<
typename _Tp,
typename _Up>
532 operator()(shared_ptr<_Tp>
const& __lhs,
533 weak_ptr<_Up>
const& __rhs)
const
534 {
return __lhs.owner_before(__rhs); }
536 template<
typename _Tp,
typename _Up>
540 {
return __lhs.owner_before(__rhs); }
542 template<
typename _Tp,
typename _Up>
544 operator()(weak_ptr<_Tp>
const& __lhs,
545 weak_ptr<_Up>
const& __rhs)
const
546 {
return __lhs.owner_before(__rhs); }
548 typedef void is_transparent;
552 template<
typename _Tp>
554 atomic_is_lock_free(
const shared_ptr<_Tp>* __p)
555 {
return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }
557 template<
typename _Tp>
558 shared_ptr<_Tp> atomic_load(
const shared_ptr<_Tp>* __p)
559 {
return std::atomic_load<_Tp>(__p); }
561 template<
typename _Tp>
563 atomic_load_explicit(
const shared_ptr<_Tp>* __p,
memory_order __mo)
564 {
return std::atomic_load_explicit<_Tp>(__p, __mo); }
566 template<
typename _Tp>
567 void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
568 {
return std::atomic_store<_Tp>(__p, __r); }
570 template<
typename _Tp>
572 atomic_store_explicit(
const shared_ptr<_Tp>* __p,
575 {
return std::atomic_store_explicit<_Tp>(__p, __r, __mo); }
577 template<
typename _Tp>
578 void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
579 {
return std::atomic_exchange<_Tp>(__p, __r); }
581 template<
typename _Tp>
583 atomic_exchange_explicit(
const shared_ptr<_Tp>* __p,
586 {
return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); }
588 template<
typename _Tp>
589 bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p,
590 shared_ptr<_Tp>* __v,
592 {
return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); }
594 template<
typename _Tp>
595 bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p,
596 shared_ptr<_Tp>* __v,
598 {
return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); }
600 template<
typename _Tp>
601 bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
602 shared_ptr<_Tp>* __v,
606 {
return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w,
610 template<
typename _Tp>
611 bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
612 shared_ptr<_Tp>* __v,
616 {
return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w,
621 template<
typename _Tp>
622 class enable_shared_from_this
625 constexpr enable_shared_from_this() noexcept { }
627 enable_shared_from_this(
const enable_shared_from_this&)
noexcept { }
629 enable_shared_from_this&
630 operator=(
const enable_shared_from_this&)
noexcept
633 ~enable_shared_from_this() { }
638 {
return shared_ptr<_Tp>(this->_M_weak_this); }
640 shared_ptr<const _Tp>
641 shared_from_this()
const
642 {
return shared_ptr<const _Tp>(this->_M_weak_this); }
645 weak_from_this() noexcept
646 {
return _M_weak_this; }
649 weak_from_this() const noexcept
650 {
return _M_weak_this; }
653 template<
typename _Tp1>
655 _M_weak_assign(_Tp1* __p,
const __shared_count<>& __n)
const noexcept
656 { _M_weak_this._M_assign(__p, __n); }
659 friend const enable_shared_from_this*
660 __expt_enable_shared_from_this_base(
const enable_shared_from_this* __p)
664 friend class shared_ptr;
666 mutable weak_ptr<_Tp> _M_weak_this;
672 template<
typename _Tp>
674 :
public __hash_base<size_t, experimental::shared_ptr<_Tp>>
677 operator()(
const experimental::shared_ptr<_Tp>& __s)
const noexcept
681_GLIBCXX_END_NAMESPACE_VERSION
typename common_type< _Tp... >::type common_type_t
Alias template for common_type.
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
__bool_constant< false > false_type
The type used as a compile-time boolean with false value.
auto declval() noexcept -> decltype(__declval< _Tp >(0))
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
memory_order
Enumeration for memory_order.
ISO C++ entities toplevel namespace is std.
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Namespace for features defined in ISO Technical Specifications.
_Del * get_deleter(const shared_ptr< _Tp > &__p) noexcept
C++14 20.8.2.2.10.
constexpr _Iterator __base(_Iterator __it)
Template class basic_ostream.
Primary class template hash.
A smart pointer with reference-counted copy semantics.
A non-owning observer for a pointer owned by a shared_ptr.
Primary template owner_less.