#include <memory>
namespace std {
template<typename T, typename D = default_delete<T>>
class intrusive_base;
template<typename T>
class intrusive_ptr;
template<typename T>
class intrusive_weak_ptr;
template<typename T, class D>
class intrusive_base {
public:
constexpr intrusive_base() noexcept;
constexpr intrusive_base(const intrusive_base & rhs) noexcept;
intrusive_base & operator=(const intrusive_base & rhs) noexcept;
~intrusive_base();
public:
const deleter_type & get_deleter() const noexcept;
deleter_type & get_deleter() noexcept;
bool unique() const volatile noexcept;
long use_count() const volatile noexcept;
long weak_count() const noexcept;
void reserve_weak() const volatile;
template<typename U = T> intrusive_ptr<const volatile U> shared_from_this() const volatile noexcept;
template<typename U = T> intrusive_ptr<const U> shared_from_this() const noexcept;
template<typename U = T> intrusive_ptr<volatile U> shared_from_this() volatile noexcept;
template<typename U = T> intrusive_ptr<U> shared_from_this() noexcept;
template<typename U = T> intrusive_weak_ptr<const volatile U> weak_from_this() const volatile;
template<typename U = T> intrusive_weak_ptr<const U> weak_from_this() const;
template<typename U = T> intrusive_weak_ptr<volatile U> weak_from_this() volatile;
template<typename U = T> intrusive_weak_ptr<U> weak_from_this();
};
template<typename T>
class intrusive_ptr {
public:
using pointer = T *;
using element_type = T;
using deleter_type = /* see below */;
constexpr intrusive_ptr(nullptr_t = nullptr) noexcept;
explicit constexpr intrusive_ptr(element_type * rhs) noexcept;
template<typename U, typename E> intrusive_ptr(unique_ptr<U, E> && rhs) noexcept;
template<typename U> intrusive_ptr(const intrusive_ptr<U> & rhs) noexcept;
template<typename U> intrusive_ptr(intrusive_ptr<U> && rhs) noexcept;
intrusive_ptr(const intrusive_ptr & rhs) noexcept;
intrusive_ptr(intrusive_ptr && rhs) noexcept;
intrusive_ptr & operator=(const intrusive_ptr & rhs) noexcept;
intrusive_ptr & operator=(intrusive_ptr && rhs) noexcept;
~intrusive_ptr();
element_type * get() const noexcept;
element_type * release() noexcept;
long use_count() const noexcept;
long weak_count() const noexcept;
void reset(nullptr_t = nullptr) noexcept;
void reset(element_type * rhs) noexcept;
void swap(intrusive_ptr & rhs) noexcept;
explicit constexpr operator bool() const noexcept;
element_type & operator*() const;
element_type * operator->() const;
};
template<typename T1, typename T2> bool operator==(const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator==(const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator==(T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator!=(const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator!=(const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator!=(T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator< (const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator< (const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator< (T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator> (const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator> (const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator> (T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator<=(const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator<=(const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator<=(T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator>=(const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator>=(const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator>=(T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) noexcept;
template<typename T, typename ... Args> intrusive_ptr<T> make_intrusive(Args &&... args);
template<typename U, typename T> intrusive_ptr<U> static_pointer_cast(intrusive_ptr<T> src) noexcept;
template<typename U, typename T> intrusive_ptr<U> dynamic_pointer_cast(intrusive_ptr<T> src) noexcept;
template<typename U, typename T> intrusive_ptr<U> const_pointer_cast(intrusive_ptr<T> src) noexcept;
template<typename T>
class intrusive_weak_ptr {
public:
using pointer = typename intrusive_ptr<T>::pointer;
using element_type = typename intrusive_ptr<T>::element_type;
using deleter_type = typename intrusive_ptr<T>::deleter_type;
constexpr intrusive_weak_ptr(nullptr_t = nullptr) noexcept;
explicit intrusive_weak_ptr(element_type * rhs);
intrusive_weak_ptr(const intrusive_ptr<T> & rhs);
template<typename U> intrusive_weak_ptr(const intrusive_weak_ptr<U> & rhs) noexcept;
template<typename U> intrusive_weak_ptr(intrusive_weak_ptr<U> && rhs) noexcept;
intrusive_weak_ptr(const intrusive_weak_ptr & rhs) noexcept;
intrusive_weak_ptr(intrusive_weak_ptr && rhs) noexcept;
intrusive_weak_ptr & operator=(const intrusive_weak_ptr & rhs) noexcept;
intrusive_weak_ptr & operator=(intrusive_weak_ptr && rhs) noexcept;
~intrusive_weak_ptr();
bool expired() const noexcept;
long weak_count() const noexcept;
template<typename U = T> intrusive_ptr<U> lock() const noexcept;
void reset(nullptr_t = nullptr) noexcept;
void reset(element_type * rhs);
void swap(intrusive_weak_ptr & rhs) noexcept;
};
template<typename T> bool operator==(const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
template<typename T> bool operator!=(const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
template<typename T> bool operator< (const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
template<typename T> bool operator> (const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
template<typename T> bool operator<=(const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
template<typename T> bool operator>=(const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
template<typename T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) noexcept;
}
template<typename T, class D> class intrusive_base
T
and D
shall be complete types.intrusive_base<T, D>
shall be a public, non-ambiguous base of T
.D
shall satisfy the requirements of DefaultConstructible. None of the default constructor, the copy/move constructor, the copy/move assignment operator of D
shall throw exceptions.constexpr intrusive_base() noexcept;
use_count() == 1
.constexpr intrusive_base(const intrusive_base & rhs) noexcept;
intrusive_base()
.intrusive_base & operator=(const intrusive_base & rhs) noexcept;
*this
.~intrusive_base();
use_count() > 1
calls terminate()
.const deleter_type & get_deleter() const noexcept;
deleter_type & get_deleter() noexcept;
bool unique() const volatile noexcept;
use_count() == 1
.long use_count() const volatile noexcept;
long weak_count() const volatile noexcept;
void reserve_weak() const volatile;
intrusive_weak_ptr
was to be constructed. Construction of intrusive_weak_ptr
referring this object shall not throw any exceptions hereafter.bad_alloc
, or an implementation-defined exception when a resource other than memory could not be obtained.template<typename U = T> intrusive_ptr<const volatile U> shared_from_this() const volatile noexcept;
template<typename U = T> intrusive_ptr<const U> shared_from_this() const noexcept;
template<typename U = T> intrusive_ptr<volatile U> shared_from_this() volatile noexcept;
template<typename U = T> intrusive_ptr<U> shared_from_this() noexcept;
pu
be the result of conversion from this
to type cv U *
. If pu
is not null, increments the reference count of pu
.intrusive_ptr<cv U>(pu)
.pu
is not null, use_count()
is one greater than the value before the call.template<typename U = T> intrusive_weak_ptr<const volatile U> weak_from_this() const volatile;
template<typename U = T> intrusive_weak_ptr<const U> weak_from_this() const;
template<typename U = T> intrusive_weak_ptr<volatile U> weak_from_this() volatile;
template<typename U = T> intrusive_weak_ptr<U> weak_from_this();
intrusive_weak_ptr<cv U>(shared_from_this())
, as if shared_from_this()
had never returned a null pointer.reserve_weak()
.weak_count()
is one greater than the value before the call.template<typename T> class intrusive_ptr
T
shall be a complete type.intrusive_base<T, D>
be a public, non-ambiguous base of T
. deleter_type
is the template parameter D
. If no such base can be found, the program is ill-formed.constexpr intrusive_ptr(nullptr_t = nullptr) noexcept;
get() == nullptr
and use_count() == 0
and weak_count() == 0
.explicit constexpr intrusive_ptr(element_type * rhs) noexcept;
rhs
is not null, increments the reference count of *rhs
.get() == rhs
. If rhs
is not null, rhs->use_count()
is one greater than the value before the call.template<typename U, typename E> intrusive_ptr(unique_ptr<U, E> && rhs) noexcept;
U *
is implicitly convertible to T *
and E
is implicitly convertible to D
.intrusive_ptr(rhs.release())
.template<typename U> intrusive_ptr(const intrusive_ptr<U> & rhs) noexcept;
U *
is implicitly convertible to T *
.rhs
is not null, increments the reference count of *rhs
.get() == rhs.get()
and use_count() == rhs.use_count()
. If rhs.use_count()
is greater than zero before the call, use_count()
is one greater than that value.template<typename U> intrusive_ptr(intrusive_ptr<U> && rhs) noexcept;
U *
is implicitly convertible to T *
.get()
equals the value of rhs.get()
before the call and rhs.get() == nullptr
. use_count()
equals the value of rhs.use_count()
before the call and rhs.use_count() == 0
.intrusive_ptr(const intrusive_ptr & rhs) noexcept;
intrusive_ptr(rhs.get())
intrusive_ptr(intrusive_ptr && rhs) noexcept;
intrusive_ptr(rhs.release())
intrusive_ptr & operator=(const intrusive_ptr & rhs) noexcept;
intrusive_ptr(rhs).swap(*this)
.intrusive_ptr & operator=(intrusive_ptr && rhs) noexcept;
reset()
followed by rhs.swap(*this)
.~intrusive_ptr();
Effects: If get()
is not null, decrements the reference count of *get()
, and if the result is zero, deletes the object as follows:
using base = intrusive_base<T, D>;
auto d = move(get()->base::get_deleter());
move(d)(get());
element_type * get() const noexcept;
element_type * release() noexcept;
nullptr
without deleting any objects.get()
before the call.get() == nullptr
.long use_count() const noexcept;
get()
is null, 0
. Otherwise, get()->intrusive_base<T, D>::use_count()
.long weak_count() const noexcept;
get()
is null, 0
. Otherwise, get()->intrusive_base<T, D>::weak_count()
.void reset(nullptr_t = nullptr) noexcept;
intrusive_ptr().swap(*this)
.void reset(element_type * rhs) noexcept;
intrusive_ptr(rhs).swap(*this)
.void swap(intrusive_ptr & rhs) noexcept;
get()
equals the value of rhs.get()
before the call and rhs.get()
equals the value of get()
before the call. use_count()
equals the value of rhs.use_count()
before the call and rhs.use_count()
equals the value of use_count()
before the call.explicit constexpr operator bool() const noexcept;
get() != nullptr
.element_type & operator*() const;
get()
shall not be null.*get()
.element_type * operator->() const;
get()
shall not be null.get()
.template<typename T1, typename T2> bool operator==(const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator==(const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator==(T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
lhs.get() == rhs.get()
, lhs.get() == rhs
and lhs == rhs.get()
, respectively.template<typename T1, typename T2> bool operator!=(const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator!=(const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator!=(T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
lhs.get() != rhs.get()
, lhs.get() != rhs
and lhs != rhs.get()
, respectively.template<typename T1, typename T2> bool operator<(const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator<(const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator<(T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
lhs.get() < rhs.get()
, lhs.get() < rhs
and lhs < rhs.get()
, respectively.template<typename T1, typename T2> bool operator>(const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator>(const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator>(T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
lhs.get() > rhs.get()
, lhs.get() > rhs
and lhs > rhs.get()
, respectively.template<typename T1, typename T2> bool operator<=(const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator<=(const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator<=(T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
lhs.get() <= rhs.get()
, lhs.get() <= rhs
and lhs <= rhs.get()
, respectively.template<typename T1, typename T2> bool operator>=(const intrusive_ptr<T1> & lhs, const intrusive_ptr<T2> & rhs) noexcept;
template<typename T1, typename T2> bool operator>=(const intrusive_ptr<T1> & lhs, T2 * rhs) noexcept;
template<typename T1, typename T2> bool operator>=(T1 * lhs, const intrusive_ptr<T2> & rhs) noexcept;
lhs.get() >= rhs.get()
, lhs.get() >= rhs
and lhs >= rhs.get()
, respectively.template<typename T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) noexcept;
lhs.swap(rhs)
.template<typename T, typename ... Args> intrusive_ptr<T> make_intrusive(Args &&... args);
intrusive_ptr<T>(new T(forward<Args>(args)...))
.template<typename U, typename T> intrusive_ptr<U> static_pointer_cast(intrusive_ptr<T> src) noexcept;
u
be the result of static_cast<U *>(src.get())
. Calls src.release()
.intrusive_ptr<U>(u)
.template<typename U, typename T> intrusive_ptr<U> dynamic_pointer_cast(intrusive_ptr<T> src) noexcept;
u
be the result of dynamic_cast<U *>(src.get())
. If u
is not null, calls src.release()
.intrusive_ptr<U>(u)
.template<typename U, typename T> intrusive_ptr<U> const_pointer_cast(intrusive_ptr<T> src) noexcept;
u
be the result of const_cast<U *>(src.get())
. Calls src.release()
.intrusive_ptr<U>(u)
.template<typename T> class intrusive_weak_ptr
T
shall be a complete type.intrusive_base<T, D>
be a public, non-ambiguous base of T
. deleter_type
is the template parameter D
. If no such base can be found, the program is ill-formed.constexpr intrusive_weak_ptr(nullptr_t = nullptr) noexcept;
expired()
and weak_count() == 0
.explicit intrusive_weak_ptr(element_type * rhs);
rhs
is not null, increments the weak reference count of *rhs
.rhs->reserve_weak()
.lock().get() == rhs
. If rhs
is not null, rhs->weak_count()
is one greater than the value before the call.intrusive_weak_ptr(const intrusive_ptr<T> & rhs);
intrusive_weak_ptr(rhs.get())
.template<typename U> intrusive_weak_ptr(const intrusive_weak_ptr<U> & rhs) noexcept;
U *
is implicitly convertible to T *
.rhs.weak_count()
is greater than zero, increments the weak reference count of the object refered by rhs
, as if it had never expired.weak_count() == rhs.weak_count()
. If rhs.weak_count()
is greater than zero before the call, weak_count()
is one greater than that value.template<typename U> intrusive_weak_ptr(intrusive_weak_ptr<U> && rhs) noexcept;
U *
is implicitly convertible to T *
.weak_count()
equals the value of rhs.weak_count()
before the call and rhs.weak_count() == 0
.intrusive_weak_ptr(const intrusive_weak_ptr & rhs) noexcept;
intrusive_weak_ptr(rhs.lock().get())
, as if the object referred by rhs
had never expired, if any.intrusive_weak_ptr(intrusive_weak_ptr && rhs) noexcept;
intrusive_weak_ptr(rhs.lock().get())
then rhs.reset()
, as if the object referred by rhs
had never expired, if any.intrusive_weak_ptr & operator=(const intrusive_weak_ptr & rhs) noexcept;
intrusive_weak_ptr(rhs).swap(*this)
.intrusive_weak_ptr & operator=(intrusive_weak_ptr && rhs) noexcept;
reset()
followed by rhs.swap(*this)
.~intrusive_weak_ptr();
pt
be a pointer to the object that *this
is referring as if that object had never expired, or a null pointer if no such object exists. If pt
is not null, decrements the weak reference count of *pt
.bool expired() const noexcept;
pt
be a pointer to the object that *this
is referring as if that object had never expired, or a null pointer if no such object exists.pt
is null, true
. Otherwise, pt->use_count() > 0
.long weak_count() const noexcept;
pt
be a pointer to the object that *this
is referring as if that object had never expired, or a null pointer if no such object exists.pt
is null, 0
. Otherwise, pt->weak_count()
.template<typename U = T> intrusive_ptr<U> lock() const noexcept;
pt
be a pointer to the object that *this
is referring as if that object had never expired, or a null pointer if no such object exists. Let pu
be the result of conversion from pu
to type U *
. If pu
is not null, increments the reference count of pu
.intrusive_ptr<U>(pu)
.pu
is not null, use_count()
is one greater than pt->intrusive_base<T, D>::use_count()
before the call.void reset(nullptr_t = nullptr) noexcept;
intrusive_weak_ptr().swap(*this)
.void reset(element_type * rhs);
intrusive_weak_ptr(rhs).swap(*this)
.void swap(intrusive_weak_ptr & rhs) noexcept;
lock()
equals the value of rhs.lock()
before the call and rhs.lock()
equals the value of lock()
before the call. weak_count()
equals the value of rhs.weak_count()
before the call and rhs.weak_count()
equals the value of weak_count()
before the call.template<typename T> bool operator==(const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
template<typename T> bool operator!=(const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
template<typename T> bool operator< (const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
template<typename T> bool operator> (const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
template<typename T> bool operator<=(const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
template<typename T> bool operator>=(const intrusive_weak_ptr<T> & lhs, const intrusive_weak_ptr<T> & rhs) const noexcept;
intrusive_weak_ptr
, enabling use of intrusive_weak_ptr
in associative containers.template<typename T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) noexcept;
lhs.swap(rhs)
.