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
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>
75 using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
77 template<
typename _Tp1,
typename _Res =
void>
79 = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
81 template<
typename _Tp1,
typename _Del,
82 typename _Ptr =
typename unique_ptr<_Tp1, _Del>::pointer,
84 using _UniqCompatible = enable_if_t<
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
130 : _Base_type(
std::move(__r)) { }
132 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
133 shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
134 : _Base_type(
std::move(__r)) { }
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 template<
typename _Tp1,
typename = _Compatible<_Tp1>>
144 : _Base_type(
std::move(__r))
145 { _M_enable_shared_from_this_with(static_cast<_Tp1*>(this->
get())); }
148 template<
typename _Tp1,
typename _Del,
149 typename = _UniqCompatible<_Tp1, _Del>>
150 shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
151 : _Base_type(
std::move(__r))
155 using __elem_t =
typename unique_ptr<_Tp1, _Del>::element_type;
156 _M_enable_shared_from_this_with(static_cast<__elem_t*>(this->
get()));
159 constexpr shared_ptr(nullptr_t __p)
160 : _Base_type(__p) { }
163 ~shared_ptr() =
default;
166 shared_ptr& operator=(
const shared_ptr&) noexcept = default;
168 template <typename _Tp1>
169 _Compatible<_Tp1, shared_ptr&>
170 operator=(const shared_ptr<_Tp1>& __r) noexcept
172 _Base_type::operator=(__r);
177 operator=(shared_ptr&& __r) noexcept
179 _Base_type::operator=(std::move(__r));
183 template <
typename _Tp1>
184 _Compatible<_Tp1, shared_ptr&>
185 operator=(shared_ptr<_Tp1>&& __r) noexcept
187 _Base_type::operator=(std::move(__r));
191 #if _GLIBCXX_USE_DEPRECATED 192 template<
typename _Tp1>
193 _Compatible<_Tp1, shared_ptr&>
196 __shared_ptr<_Tp>::operator=(std::move(__r));
201 template <
typename _Tp1,
typename _Del>
202 _UniqCompatible<_Tp1, _Del, shared_ptr&>
203 operator=(unique_ptr<_Tp1, _Del>&& __r)
205 _Base_type::operator=(std::move(__r));
215 template<
typename _Alloc,
typename... _Args>
216 shared_ptr(_Sp_make_shared_tag __tag,
const _Alloc& __a,
218 : _Base_type(__tag, __a,
std::
forward<_Args>(__args)...)
219 { _M_enable_shared_from_this_with(this->
get()); }
221 template<
typename _Tp1,
typename _Alloc,
typename... _Args>
222 friend shared_ptr<_Tp1>
225 shared_ptr(
const weak_ptr<_Tp>& __r, std::nothrow_t)
226 : _Base_type(__r,
std::nothrow) { }
228 friend class weak_ptr<_Tp>;
230 template<
typename _Yp>
231 using __esft_base_t =
232 decltype(__expt_enable_shared_from_this_base(std::declval<_Yp*>()));
235 template<
typename _Yp,
typename =
void>
236 struct __has_esft_base
239 template<
typename _Yp>
240 struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
241 : __bool_constant<!is_array_v<_Tp>> { };
243 template<
typename _Yp>
244 typename enable_if<__has_esft_base<_Yp>::value>::type
245 _M_enable_shared_from_this_with(
const _Yp* __p) noexcept
247 if (
auto __base = __expt_enable_shared_from_this_base(__p))
250 = shared_ptr<_Yp>(*
this,
const_cast<_Yp*
>(__p));
254 template<
typename _Yp>
255 typename enable_if<!__has_esft_base<_Yp>::value>::type
256 _M_enable_shared_from_this_with(
const _Yp*) noexcept
261 template<
typename _Tp1,
typename _Tp2>
262 bool operator==(
const shared_ptr<_Tp1>& __a,
263 const shared_ptr<_Tp2>& __b) noexcept
264 {
return __a.get() == __b.get(); }
266 template<
typename _Tp>
268 operator==(
const shared_ptr<_Tp>& __a, nullptr_t) noexcept
271 template<
typename _Tp>
273 operator==(nullptr_t,
const shared_ptr<_Tp>& __a) noexcept
276 template<
typename _Tp1,
typename _Tp2>
278 operator!=(
const shared_ptr<_Tp1>& __a,
279 const shared_ptr<_Tp2>& __b) noexcept
280 {
return __a.get() != __b.get(); }
282 template<
typename _Tp>
284 operator!=(
const shared_ptr<_Tp>& __a, nullptr_t) noexcept
285 {
return (
bool)__a; }
287 template<
typename _Tp>
289 operator!=(nullptr_t,
const shared_ptr<_Tp>& __a) noexcept
290 {
return (
bool)__a; }
292 template<
typename _Tp1,
typename _Tp2>
294 operator<(const shared_ptr<_Tp1>& __a,
295 const shared_ptr<_Tp2>& __b) noexcept
297 using __elem_t1 =
typename shared_ptr<_Tp1>::element_type;
298 using __elem_t2 =
typename shared_ptr<_Tp2>::element_type;
299 using _CT = common_type_t<__elem_t1*, __elem_t2*>;
303 template<
typename _Tp>
305 operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
307 using __elem_t =
typename shared_ptr<_Tp>::element_type;
311 template<
typename _Tp>
313 operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
315 using __elem_t =
typename shared_ptr<_Tp>::element_type;
319 template<
typename _Tp1,
typename _Tp2>
321 operator<=(const shared_ptr<_Tp1>& __a,
322 const shared_ptr<_Tp2>& __b) noexcept
323 {
return !(__b < __a); }
325 template<
typename _Tp>
327 operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
328 {
return !(
nullptr < __a); }
330 template<
typename _Tp>
332 operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
333 {
return !(__a <
nullptr); }
335 template<
typename _Tp1,
typename _Tp2>
337 operator>(
const shared_ptr<_Tp1>& __a,
338 const shared_ptr<_Tp2>& __b) noexcept
339 {
return (__b < __a); }
341 template<
typename _Tp>
343 operator>(
const shared_ptr<_Tp>& __a, nullptr_t) noexcept
345 using __elem_t =
typename shared_ptr<_Tp>::element_type;
349 template<
typename _Tp>
351 operator>(nullptr_t,
const shared_ptr<_Tp>& __a) noexcept
353 using __elem_t =
typename shared_ptr<_Tp>::element_type;
357 template<
typename _Tp1,
typename _Tp2>
359 operator>=(
const shared_ptr<_Tp1>& __a,
360 const shared_ptr<_Tp2>& __b) noexcept
361 {
return !(__a < __b); }
363 template<
typename _Tp>
365 operator>=(
const shared_ptr<_Tp>& __a, nullptr_t) noexcept
366 {
return !(__a <
nullptr); }
368 template<
typename _Tp>
370 operator>=(nullptr_t,
const shared_ptr<_Tp>& __a) noexcept
371 {
return !(
nullptr < __a); }
374 template<
typename _Tp>
376 swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
380 template<
typename _Tp,
typename _Tp1>
381 inline shared_ptr<_Tp>
382 static_pointer_cast(
const shared_ptr<_Tp1>& __r) noexcept
384 using __elem_t =
typename shared_ptr<_Tp>::element_type;
385 return shared_ptr<_Tp>(__r,
static_cast<__elem_t*
>(__r.get()));
388 template<
typename _Tp,
typename _Tp1>
389 inline shared_ptr<_Tp>
390 dynamic_pointer_cast(
const shared_ptr<_Tp1>& __r) noexcept
392 using __elem_t =
typename shared_ptr<_Tp>::element_type;
393 if (_Tp* __p = dynamic_cast<__elem_t*>(__r.get()))
394 return shared_ptr<_Tp>(__r, __p);
395 return shared_ptr<_Tp>();
398 template<
typename _Tp,
typename _Tp1>
399 inline shared_ptr<_Tp>
400 const_pointer_cast(
const shared_ptr<_Tp1>& __r) noexcept
402 using __elem_t =
typename shared_ptr<_Tp>::element_type;
403 return shared_ptr<_Tp>(__r,
const_cast<__elem_t*
>(__r.get()));
406 template<
typename _Tp,
typename _Tp1>
407 inline shared_ptr<_Tp>
408 reinterpret_pointer_cast(
const shared_ptr<_Tp1>& __r) noexcept
410 using __elem_t =
typename shared_ptr<_Tp>::element_type;
411 return shared_ptr<_Tp>(__r,
reinterpret_cast<__elem_t*
>(__r.get()));
415 template<
typename _Tp>
416 class weak_ptr :
public __weak_ptr<_Tp>
418 template<
typename _Tp1,
typename _Res =
void>
419 using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
421 using _Base_type = __weak_ptr<_Tp>;
424 constexpr weak_ptr() noexcept = default;
426 template<typename _Tp1, typename = _Compatible<_Tp1>>
427 weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
428 : _Base_type(__r) { }
430 weak_ptr(
const weak_ptr&) noexcept = default;
432 template<typename _Tp1, typename = _Compatible<_Tp1>>
433 weak_ptr(const weak_ptr<_Tp1>& __r) noexcept
434 : _Base_type(__r) { }
436 weak_ptr(weak_ptr&&) noexcept = default;
438 template<typename _Tp1, typename = _Compatible<_Tp1>>
439 weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
440 : _Base_type(
std::move(__r)) { }
443 operator=(
const weak_ptr& __r) noexcept =
default;
445 template<
typename _Tp1>
446 _Compatible<_Tp1, weak_ptr&>
447 operator=(
const weak_ptr<_Tp1>& __r) noexcept
449 this->_Base_type::operator=(__r);
453 template<
typename _Tp1>
454 _Compatible<_Tp1, weak_ptr&>
455 operator=(
const shared_ptr<_Tp1>& __r) noexcept
457 this->_Base_type::operator=(__r);
462 operator=(weak_ptr&& __r) noexcept = default;
464 template<typename _Tp1>
465 _Compatible<_Tp1, weak_ptr&>
466 operator=(weak_ptr<_Tp1>&& __r) noexcept
468 this->_Base_type::operator=(std::move(__r));
473 lock() const noexcept
474 {
return shared_ptr<_Tp>(*
this, std::nothrow); }
476 friend class enable_shared_from_this<_Tp>;
480 template<
typename _Tp>
482 swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
486 template<
typename _Del,
typename _Tp>
489 {
return std::get_deleter<_Del>(__p); }
492 template<
typename _Ch,
typename _Tr,
typename _Tp>
494 operator<<(std::basic_ostream<_Ch, _Tr>& __os,
const shared_ptr<_Tp>& __p)
501 template<
typename _Tp =
void>
class owner_less;
504 template<
typename _Tp>
505 struct owner_less<shared_ptr<_Tp>>
506 :
public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
510 template<
typename _Tp>
511 struct owner_less<weak_ptr<_Tp>>
512 :
public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
516 class owner_less<void>
518 template<
typename _Tp,
typename _Up>
520 operator()(shared_ptr<_Tp>
const& __lhs,
521 shared_ptr<_Up>
const& __rhs)
const 522 {
return __lhs.owner_before(__rhs); }
524 template<
typename _Tp,
typename _Up>
526 operator()(shared_ptr<_Tp>
const& __lhs,
527 weak_ptr<_Up>
const& __rhs)
const 528 {
return __lhs.owner_before(__rhs); }
530 template<
typename _Tp,
typename _Up>
532 operator()(weak_ptr<_Tp>
const& __lhs,
533 shared_ptr<_Up>
const& __rhs)
const 534 {
return __lhs.owner_before(__rhs); }
536 template<
typename _Tp,
typename _Up>
538 operator()(weak_ptr<_Tp>
const& __lhs,
539 weak_ptr<_Up>
const& __rhs)
const 540 {
return __lhs.owner_before(__rhs); }
542 typedef void is_transparent;
546 template<
typename _Tp>
548 atomic_is_lock_free(
const shared_ptr<_Tp>* __p)
549 {
return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }
551 template<
typename _Tp>
552 shared_ptr<_Tp> atomic_load(
const shared_ptr<_Tp>* __p)
553 {
return std::atomic_load<_Tp>(__p); }
555 template<
typename _Tp>
557 atomic_load_explicit(
const shared_ptr<_Tp>* __p,
memory_order __mo)
558 {
return std::atomic_load_explicit<_Tp>(__p, __mo); }
560 template<
typename _Tp>
561 void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
562 {
return std::atomic_store<_Tp>(__p, __r); }
564 template<
typename _Tp>
566 atomic_store_explicit(
const shared_ptr<_Tp>* __p,
569 {
return std::atomic_store_explicit<_Tp>(__p, __r, __mo); }
571 template<
typename _Tp>
572 void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
573 {
return std::atomic_exchange<_Tp>(__p, __r); }
575 template<
typename _Tp>
577 atomic_exchange_explicit(
const shared_ptr<_Tp>* __p,
580 {
return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); }
582 template<
typename _Tp>
583 bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p,
584 shared_ptr<_Tp>* __v,
586 {
return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); }
588 template<
typename _Tp>
589 bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p,
590 shared_ptr<_Tp>* __v,
592 {
return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); }
594 template<
typename _Tp>
595 bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
596 shared_ptr<_Tp>* __v,
600 {
return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w,
604 template<
typename _Tp>
605 bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
606 shared_ptr<_Tp>* __v,
610 {
return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w,
615 template<
typename _Tp>
616 class enable_shared_from_this
619 constexpr enable_shared_from_this() noexcept { }
621 enable_shared_from_this(
const enable_shared_from_this&) noexcept { }
623 enable_shared_from_this&
624 operator=(
const enable_shared_from_this&) noexcept
627 ~enable_shared_from_this() { }
632 {
return shared_ptr<_Tp>(this->_M_weak_this); }
634 shared_ptr<const _Tp>
635 shared_from_this()
const 636 {
return shared_ptr<const _Tp>(this->_M_weak_this); }
639 weak_from_this() noexcept
640 {
return _M_weak_this; }
643 weak_from_this()
const noexcept
644 {
return _M_weak_this; }
647 template<
typename _Tp1>
649 _M_weak_assign(_Tp1* __p,
const __shared_count<>& __n)
const noexcept
650 { _M_weak_this._M_assign(__p, __n); }
653 friend const enable_shared_from_this*
654 __expt_enable_shared_from_this_base(
const enable_shared_from_this* __p)
658 friend class shared_ptr;
660 mutable weak_ptr<_Tp> _M_weak_this;
663 _GLIBCXX_END_NAMESPACE_VERSION
667 _GLIBCXX_BEGIN_NAMESPACE_VERSION
670 template<
typename _Tp>
671 struct hash<experimental::shared_ptr<_Tp>>
672 :
public __hash_base<size_t, experimental::shared_ptr<_Tp>>
675 operator()(
const experimental::shared_ptr<_Tp>& __s)
const noexcept
679 _GLIBCXX_END_NAMESPACE_VERSION
682 #endif // __cplusplus <= 201103L 684 #endif // _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H
A simple smart pointer providing strict ownership semantics.
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.
memory_order
Enumeration for memory_order.
Partial specializations for pointer types.
ISO C++ entities toplevel namespace is std.
One of the comparison functors.
_Del * get_deleter(const __shared_ptr< _Tp, _Lp > &__p) noexcept
20.7.2.2.10 shared_ptr get_deleter
shared_ptr< _Tp > allocate_shared(const _Alloc &__a, _Args &&...__args)
Create an object that is owned by a shared_ptr.
void lock(_L1 &__l1, _L2 &__l2, _L3 &...__l3)
Generic lock.
Primary class template hash.