30#ifndef _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 
   31#define _GLIBCXX_EXPERIMENTAL_SHARED_PTR_H 1 
   33#pragma GCC system_header 
   35#if __cplusplus >= 201402L 
   40namespace std _GLIBCXX_VISIBILITY(default)
 
   42_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   46inline namespace fundamentals_v2
 
   50  template<
typename _Tp> 
class shared_ptr;
 
   51  template<
typename _Tp> 
class weak_ptr;
 
   52  template<
typename _Tp> 
class enable_shared_from_this;
 
   54  template<
typename _Yp, 
typename _Tp>
 
   55    constexpr bool __sp_compatible_v
 
   56      = std::__sp_compatible_with<_Yp*, _Tp*>::value;
 
   58  template<
typename _Tp, 
typename _Yp>
 
   59    constexpr bool __sp_is_constructible_v
 
   60      = std::__sp_is_constructible<_Tp, _Yp>::value;
 
   62  template<
typename _Tp>
 
   63    class shared_ptr : 
public __shared_ptr<_Tp>
 
   65      using _Base_type = __shared_ptr<_Tp>;
 
   68      using element_type = 
typename _Base_type::element_type;
 
   72      template<
typename _Yp>
 
   73        using _SafeConv = enable_if_t<__sp_is_constructible_v<_Tp, _Yp>>;
 
   75      template<
typename _Tp1, 
typename _Res = 
void>
 
   77          = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
 
   79      template<
typename _Tp1, 
typename _Del,
 
   80               typename _Ptr = 
typename unique_ptr<_Tp1, _Del>::pointer,
 
   83          __sp_compatible_v<_Tp1, _Tp>
 
   84          && experimental::is_convertible_v<_Ptr, element_type*>,
 
   90      constexpr shared_ptr() noexcept = default;
 
   92      template<typename _Tp1, typename = _SafeConv<_Tp1>>
 
   94        shared_ptr(_Tp1* __p) : _Base_type(__p)
 
   95        { _M_enable_shared_from_this_with(__p); }
 
   97      template<
typename _Tp1, 
typename _Deleter, 
typename = _SafeConv<_Tp1>>
 
   98        shared_ptr(_Tp1* __p, _Deleter __d)
 
   99        : _Base_type(__p, __d)
 
  100        { _M_enable_shared_from_this_with(__p); }
 
  102      template<
typename _Tp1, 
typename _Deleter, 
typename _Alloc,
 
  103               typename = _SafeConv<_Tp1>>
 
  104        shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)
 
  105        : _Base_type(__p, __d, __a)
 
  106        { _M_enable_shared_from_this_with(__p); }
 
  108      template<
typename _Deleter>
 
  109        shared_ptr(nullptr_t __p, _Deleter __d)
 
  110        : _Base_type(__p, __d) { }
 
  112      template<
typename _Deleter, 
typename _Alloc>
 
  113        shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
 
  114        : _Base_type(__p, __d, __a) { }
 
  116      template<
typename _Tp1>
 
  117        shared_ptr(
const shared_ptr<_Tp1>& __r, element_type* __p) noexcept
 
  118        : _Base_type(__r, __p) { }
 
  120      shared_ptr(
const shared_ptr& __r) noexcept
 
  121        : _Base_type(__r) { }
 
  123      template<
typename _Tp1, 
typename = _Compatible<_Tp1>>
 
  124        shared_ptr(
const shared_ptr<_Tp1>& __r) noexcept
 
  125        : _Base_type(__r) { }
 
  127      shared_ptr(shared_ptr&& __r) noexcept
 
  130      template<
typename _Tp1, 
typename = _Compatible<_Tp1>>
 
  131        shared_ptr(shared_ptr<_Tp1>&& __r) noexcept
 
  134      template<
typename _Tp1, 
typename = _Compatible<_Tp1>>
 
  136        shared_ptr(
const weak_ptr<_Tp1>& __r)
 
  137        : _Base_type(__r) { }
 
  139#if _GLIBCXX_USE_DEPRECATED 
  140#pragma GCC diagnostic push 
  141#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 
  142      template<
typename _Tp1, 
typename = _Compatible<_Tp1>>
 
  145        { _M_enable_shared_from_this_with(
static_cast<_Tp1*
>(this->get())); }
 
  146#pragma GCC diagnostic pop 
  149      template<
typename _Tp1, 
typename _Del,
 
  150               typename = _UniqCompatible<_Tp1, _Del>>
 
  151        shared_ptr(unique_ptr<_Tp1, _Del>&& __r)
 
  156          using __elem_t = 
typename unique_ptr<_Tp1, _Del>::element_type;
 
  157          _M_enable_shared_from_this_with(
static_cast<__elem_t*
>(this->get()));
 
  160      constexpr shared_ptr(nullptr_t __p)
 
  161      : _Base_type(__p) { }
 
  164      ~shared_ptr() = 
default;
 
  167      shared_ptr& operator=(
const shared_ptr&) 
noexcept = 
default;
 
  169      template <
typename _Tp1>
 
  170        _Compatible<_Tp1, shared_ptr&>
 
  171        operator=(
const shared_ptr<_Tp1>& __r) 
noexcept 
  173          _Base_type::operator=(__r);
 
  178      operator=(shared_ptr&& __r) 
noexcept 
  184      template <
typename _Tp1>
 
  185        _Compatible<_Tp1, shared_ptr&>
 
  186        operator=(shared_ptr<_Tp1>&& __r) 
noexcept 
  192#if _GLIBCXX_USE_DEPRECATED 
  193#pragma GCC diagnostic push 
  194#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 
  195      template<
typename _Tp1>
 
  196        _Compatible<_Tp1, shared_ptr&>
 
  199          __shared_ptr<_Tp>::operator=(
std::move(__r));
 
  202#pragma GCC diagnostic pop 
  205      template <
typename _Tp1, 
typename _Del>
 
  206        _UniqCompatible<_Tp1, _Del, shared_ptr&>
 
  207        operator=(unique_ptr<_Tp1, _Del>&& __r)
 
  219      template<
typename _Alloc, 
typename... _Args>
 
  220        shared_ptr(_Sp_make_shared_tag __tag, 
const _Alloc& __a,
 
  222        : _Base_type(__tag, __a, 
std::
forward<_Args>(__args)...)
 
  223        { _M_enable_shared_from_this_with(this->get()); }
 
  225      template<
typename _Tp1, 
typename _Alloc, 
typename... _Args>
 
  226        friend shared_ptr<_Tp1>
 
  227        allocate_shared(
const _Alloc& __a, _Args&&...  __args);
 
  229      shared_ptr(
const weak_ptr<_Tp>& __r, std::nothrow_t)
 
  230      : _Base_type(__r, 
std::nothrow) { }
 
  232      friend class weak_ptr<_Tp>;
 
  234      template<
typename _Yp>
 
  235        using __esft_base_t =
 
  236          decltype(__expt_enable_shared_from_this_base(std::declval<_Yp*>()));
 
  239      template<
typename _Yp, 
typename = 
void>
 
  240        struct __has_esft_base
 
  243      template<
typename _Yp>
 
  244        struct __has_esft_base<_Yp, __void_t<__esft_base_t<_Yp>>>
 
  245        : __bool_constant<!is_array_v<_Tp>> { };  
 
  247      template<
typename _Yp>
 
  248        typename enable_if<__has_esft_base<_Yp>::value>::type
 
  249        _M_enable_shared_from_this_with(
const _Yp* __p) 
noexcept 
  251          if (
auto __base = __expt_enable_shared_from_this_base(__p))
 
  254                = shared_ptr<_Yp>(*
this, 
const_cast<_Yp*
>(__p));
 
  258      template<
typename _Yp>
 
  259        typename enable_if<!__has_esft_base<_Yp>::value>::type
 
  260        _M_enable_shared_from_this_with(
const _Yp*) 
noexcept 
  265  template<
typename _Tp1, 
typename _Tp2>
 
  266    bool operator==(
const shared_ptr<_Tp1>& __a,
 
  267                    const shared_ptr<_Tp2>& __b) 
noexcept 
  268    { 
return __a.get() == __b.get(); }
 
  270  template<
typename _Tp>
 
  272    operator==(
const shared_ptr<_Tp>& __a, nullptr_t) 
noexcept 
  275  template<
typename _Tp>
 
  277    operator==(nullptr_t, 
const shared_ptr<_Tp>& __a) 
noexcept 
  280  template<
typename _Tp1, 
typename _Tp2>
 
  282    operator!=(
const shared_ptr<_Tp1>& __a,
 
  283               const shared_ptr<_Tp2>& __b) 
noexcept 
  284    { 
return __a.get() != __b.get(); }
 
  286  template<
typename _Tp>
 
  288    operator!=(
const shared_ptr<_Tp>& __a, nullptr_t) 
noexcept 
  289    { 
return (
bool)__a; }
 
  291  template<
typename _Tp>
 
  293    operator!=(nullptr_t, 
const shared_ptr<_Tp>& __a) 
noexcept 
  294    { 
return (
bool)__a; }
 
  296  template<
typename _Tp1, 
typename _Tp2>
 
  298    operator<(
const shared_ptr<_Tp1>& __a,
 
  299              const shared_ptr<_Tp2>& __b) 
noexcept 
  301      using __elem_t1 = 
typename shared_ptr<_Tp1>::element_type;
 
  302      using __elem_t2 = 
typename shared_ptr<_Tp2>::element_type;
 
  303      using _CT = common_type_t<__elem_t1*, __elem_t2*>;
 
  307  template<
typename _Tp>
 
  309    operator<(
const shared_ptr<_Tp>& __a, nullptr_t) 
noexcept 
  311      using __elem_t = 
typename shared_ptr<_Tp>::element_type;
 
  315  template<
typename _Tp>
 
  317    operator<(nullptr_t, 
const shared_ptr<_Tp>& __a) 
noexcept 
  319      using __elem_t = 
typename shared_ptr<_Tp>::element_type;
 
  323  template<
typename _Tp1, 
typename _Tp2>
 
  325    operator<=(
const shared_ptr<_Tp1>& __a,
 
  326               const shared_ptr<_Tp2>& __b) 
noexcept 
  327    { 
return !(__b < __a); }
 
  329  template<
typename _Tp>
 
  331    operator<=(
const shared_ptr<_Tp>& __a, nullptr_t) 
noexcept 
  332    { 
return !(
nullptr < __a); }
 
  334  template<
typename _Tp>
 
  336    operator<=(nullptr_t, 
const shared_ptr<_Tp>& __a) 
noexcept 
  337    { 
return !(__a < 
nullptr); }
 
  339  template<
typename _Tp1, 
typename _Tp2>
 
  341    operator>(
const shared_ptr<_Tp1>& __a,
 
  342              const shared_ptr<_Tp2>& __b) 
noexcept 
  343    { 
return (__b < __a); }
 
  345  template<
typename _Tp>
 
  347    operator>(
const shared_ptr<_Tp>& __a, nullptr_t) 
noexcept 
  349      using __elem_t = 
typename shared_ptr<_Tp>::element_type;
 
  353  template<
typename _Tp>
 
  355    operator>(nullptr_t, 
const shared_ptr<_Tp>& __a) 
noexcept 
  357      using __elem_t = 
typename shared_ptr<_Tp>::element_type;
 
  361  template<
typename _Tp1, 
typename _Tp2>
 
  363    operator>=(
const shared_ptr<_Tp1>& __a,
 
  364               const shared_ptr<_Tp2>& __b) 
noexcept 
  365    { 
return !(__a < __b); }
 
  367  template<
typename _Tp>
 
  369    operator>=(
const shared_ptr<_Tp>& __a, nullptr_t) 
noexcept 
  370    { 
return !(__a < 
nullptr); }
 
  372  template<
typename _Tp>
 
  374    operator>=(nullptr_t, 
const shared_ptr<_Tp>& __a) 
noexcept 
  375    { 
return !(
nullptr < __a); }
 
  378  template<
typename _Tp>
 
  380    swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) 
noexcept 
  384  template<
typename _Tp, 
typename _Tp1>
 
  385    inline shared_ptr<_Tp>
 
  388      using __elem_t = 
typename shared_ptr<_Tp>::element_type;
 
  389      return shared_ptr<_Tp>(__r, 
static_cast<__elem_t*
>(__r.get()));
 
  392  template<
typename _Tp, 
typename _Tp1>
 
  393    inline shared_ptr<_Tp>
 
  396      using __elem_t = 
typename shared_ptr<_Tp>::element_type;
 
  397      if (_Tp* __p = 
dynamic_cast<__elem_t*
>(__r.get()))
 
  398        return shared_ptr<_Tp>(__r, __p);
 
  399      return shared_ptr<_Tp>();
 
  402  template<
typename _Tp, 
typename _Tp1>
 
  403    inline shared_ptr<_Tp>
 
  406      using __elem_t = 
typename shared_ptr<_Tp>::element_type;
 
  407      return shared_ptr<_Tp>(__r, 
const_cast<__elem_t*
>(__r.get()));
 
  410  template<
typename _Tp, 
typename _Tp1>
 
  411    inline shared_ptr<_Tp>
 
  412    reinterpret_pointer_cast(
const shared_ptr<_Tp1>& __r) 
noexcept 
  414      using __elem_t = 
typename shared_ptr<_Tp>::element_type;
 
  415      return shared_ptr<_Tp>(__r, 
reinterpret_cast<__elem_t*
>(__r.get()));
 
  419  template<
typename _Tp>
 
  420    class weak_ptr : 
public __weak_ptr<_Tp>
 
  422      template<
typename _Tp1, 
typename _Res = 
void>
 
  423        using _Compatible = enable_if_t<__sp_compatible_v<_Tp1, _Tp>, _Res>;
 
  425      using _Base_type = __weak_ptr<_Tp>;
 
  428       constexpr weak_ptr() noexcept = default;
 
  430       template<typename _Tp1, typename = _Compatible<_Tp1>>
 
  431         weak_ptr(const shared_ptr<_Tp1>& __r) noexcept
 
  432         : _Base_type(__r) { }
 
  434       weak_ptr(
const weak_ptr&) 
noexcept = 
default;
 
  436       template<
typename _Tp1, 
typename = _Compatible<_Tp1>>
 
  437         weak_ptr(
const weak_ptr<_Tp1>& __r) noexcept
 
  438         : _Base_type(__r) { }
 
  440       weak_ptr(weak_ptr&&) noexcept = default;
 
  442       template<typename _Tp1, typename = _Compatible<_Tp1>>
 
  443         weak_ptr(weak_ptr<_Tp1>&& __r) noexcept
 
  444         : _Base_type(
std::
move(__r)) { }
 
  447       operator=(
const weak_ptr& __r) 
noexcept = 
default;
 
  449       template<
typename _Tp1>
 
  450         _Compatible<_Tp1, weak_ptr&>
 
  451         operator=(
const weak_ptr<_Tp1>& __r) 
noexcept 
  453           this->_Base_type::operator=(__r);
 
  457       template<
typename _Tp1>
 
  458         _Compatible<_Tp1, weak_ptr&>
 
  459         operator=(
const shared_ptr<_Tp1>& __r) 
noexcept 
  461           this->_Base_type::operator=(__r);
 
  466       operator=(weak_ptr&& __r) 
noexcept = 
default;
 
  468       template<
typename _Tp1>
 
  469         _Compatible<_Tp1, weak_ptr&>
 
  470         operator=(weak_ptr<_Tp1>&& __r) 
noexcept 
  472           this->_Base_type::operator=(
std::move(__r));
 
  477       lock() const noexcept
 
  478       { 
return shared_ptr<_Tp>(*
this, std::nothrow); }
 
  480       friend class enable_shared_from_this<_Tp>;
 
  484  template<
typename _Tp>
 
  486    swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) 
noexcept 
  490  template<
typename _Del, 
typename _Tp>
 
  492    get_deleter(
const shared_ptr<_Tp>& __p) 
noexcept 
  493    { 
return std::get_deleter<_Del>(__p); }
 
  496  template<
typename _Ch, 
typename _Tr, 
typename _Tp>
 
  505  template<
typename _Tp = 
void> 
class owner_less;
 
  508  template<
typename _Tp>
 
  509    struct owner_less<shared_ptr<_Tp>>
 
  510    : 
public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
 
  514  template<
typename _Tp>
 
  515    struct owner_less<weak_ptr<_Tp>>
 
  516    : 
public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
 
  520    class owner_less<void>
 
  522      template<
typename _Tp, 
typename _Up>
 
  524        operator()(shared_ptr<_Tp> 
const& __lhs,
 
  525                   shared_ptr<_Up> 
const& __rhs)
 const 
  526        { 
return __lhs.owner_before(__rhs); }
 
  528      template<
typename _Tp, 
typename _Up>
 
  530        operator()(shared_ptr<_Tp> 
const& __lhs,
 
  531                   weak_ptr<_Up> 
const& __rhs)
 const 
  532        { 
return __lhs.owner_before(__rhs); }
 
  534      template<
typename _Tp, 
typename _Up>
 
  538        { 
return __lhs.owner_before(__rhs); }
 
  540      template<
typename _Tp, 
typename _Up>
 
  542        operator()(weak_ptr<_Tp> 
const& __lhs,
 
  543                   weak_ptr<_Up> 
const& __rhs)
 const 
  544        { 
return __lhs.owner_before(__rhs); }
 
  546      typedef void is_transparent;
 
  550   template<
typename _Tp>
 
  552     atomic_is_lock_free(
const shared_ptr<_Tp>* __p)
 
  553     { 
return std::atomic_is_lock_free<_Tp, __default_lock_policy>(__p); }
 
  555   template<
typename _Tp>
 
  556     shared_ptr<_Tp> atomic_load(
const shared_ptr<_Tp>* __p)
 
  557     { 
return std::atomic_load<_Tp>(__p); }
 
  559   template<
typename _Tp>
 
  561     atomic_load_explicit(
const shared_ptr<_Tp>* __p, 
memory_order __mo)
 
  562     { 
return std::atomic_load_explicit<_Tp>(__p, __mo); }
 
  564   template<
typename _Tp>
 
  565     void atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
 
  566     { 
return std::atomic_store<_Tp>(__p, __r); }
 
  568   template<
typename _Tp>
 
  570     atomic_store_explicit(
const shared_ptr<_Tp>* __p,
 
  573     { 
return std::atomic_store_explicit<_Tp>(__p, __r, __mo); }
 
  575   template<
typename _Tp>
 
  576     void atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
 
  577     { 
return std::atomic_exchange<_Tp>(__p, __r); }
 
  579   template<
typename _Tp>
 
  581     atomic_exchange_explicit(
const shared_ptr<_Tp>* __p,
 
  584     { 
return std::atomic_exchange_explicit<_Tp>(__p, __r, __mo); }
 
  586   template<
typename _Tp>
 
  587     bool atomic_compare_exchange_weak(shared_ptr<_Tp>* __p,
 
  588                                       shared_ptr<_Tp>* __v,
 
  590     { 
return std::atomic_compare_exchange_weak<_Tp>(__p, __v, __w); }
 
  592   template<
typename _Tp>
 
  593     bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p,
 
  594                                         shared_ptr<_Tp>* __v,
 
  596     { 
return std::atomic_compare_exchange_strong<_Tp>(__p, __v, __w); }
 
  598   template<
typename _Tp>
 
  599     bool atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p,
 
  600                                                shared_ptr<_Tp>* __v,
 
  604     { 
return std::atomic_compare_exchange_weak_explicit<_Tp>(__p, __v, __w,
 
  608   template<
typename _Tp>
 
  609     bool atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p,
 
  610                                                  shared_ptr<_Tp>* __v,
 
  614     { 
return std::atomic_compare_exchange_strong_explicit<_Tp>(__p, __v, __w,
 
  619  template<
typename _Tp>
 
  620    class enable_shared_from_this
 
  623      constexpr enable_shared_from_this() noexcept { }
 
  625      enable_shared_from_this(
const enable_shared_from_this&) 
noexcept { }
 
  627      enable_shared_from_this&
 
  628      operator=(
const enable_shared_from_this&) 
noexcept 
  631      ~enable_shared_from_this() { }
 
  636      { 
return shared_ptr<_Tp>(this->_M_weak_this); }
 
  638      shared_ptr<const _Tp>
 
  639      shared_from_this()
 const 
  640      { 
return shared_ptr<const _Tp>(this->_M_weak_this); }
 
  643      weak_from_this() noexcept
 
  644      { 
return _M_weak_this; }
 
  647      weak_from_this() const noexcept
 
  648      { 
return _M_weak_this; }
 
  651      template<
typename _Tp1>
 
  653        _M_weak_assign(_Tp1* __p, 
const __shared_count<>& __n) 
const noexcept 
  654        { _M_weak_this._M_assign(__p, __n); }
 
  657      friend const enable_shared_from_this*
 
  658      __expt_enable_shared_from_this_base(
const enable_shared_from_this* __p)
 
  662        friend class shared_ptr;
 
  664      mutable weak_ptr<_Tp> _M_weak_this;
 
  670  template<
typename _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
 
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
 
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
 
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.
 
void lock(_L1 &__l1, _L2 &__l2, _L3 &... __l3)
Generic lock.
 
ISO C++ entities toplevel namespace is std.
 
__shared_ptr< _Tp, _Lp > dynamic_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
dynamic_pointer_cast
 
__shared_ptr< _Tp, _Lp > static_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
static_pointer_cast
 
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
 
__shared_ptr< _Tp, _Lp > const_pointer_cast(const __shared_ptr< _Tp1, _Lp > &__r) noexcept
const_pointer_cast
 
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.
 
A simple smart pointer providing strict ownership semantics.
 
One of the comparison functors.