This repository was archived by the owner on Apr 28, 2025. It is now read-only.
- Notifications
You must be signed in to change notification settings - Fork4
Proposal for std::intrusive_ptr
License
NotificationsYou must be signed in to change notification settings
lhmouse/intrusive_ptr
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
#include<memory>namespacestd {template<typename T,typename D = default_delete<T>>classintrusive_base;template<typename T>classintrusive_ptr;template<typename T>classintrusive_weak_ptr;template<typename T,classD>classintrusive_base {public:constexprintrusive_base()noexcept;constexprintrusive_base(const intrusive_base & rhs)noexcept; intrusive_base &operator=(const intrusive_base & rhs)noexcept;~intrusive_base();public:const deleter_type &get_deleter()constnoexcept; deleter_type &get_deleter()noexcept;boolunique()const volatilenoexcept;longuse_count()const volatilenoexcept;longweak_count()constnoexcept;voidreserve_weak()const volatile;template<typename U = T> intrusive_ptr<constvolatile U>shared_from_this()const volatilenoexcept;template<typename U = T> intrusive_ptr<const U>shared_from_this()constnoexcept;template<typename U = T> intrusive_ptr<volatile U>shared_from_this() volatilenoexcept;template<typename U = T> intrusive_ptr<U>shared_from_this()noexcept;template<typename U = T> intrusive_weak_ptr<constvolatile 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>classintrusive_ptr {public:using pointer = T *;using element_type = T;using deleter_type =/* see below*/;constexprintrusive_ptr(nullptr_t =nullptr)noexcept;explicitconstexprintrusive_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()constnoexcept; element_type *release()noexcept;longuse_count()constnoexcept;longweak_count()constnoexcept;voidreset(nullptr_t =nullptr)noexcept;voidreset(element_type * rhs)noexcept;voidswap(intrusive_ptr & rhs)noexcept;explicitconstexproperatorbool()constnoexcept; element_type &operator*()const; element_type *operator->()const;};template<typename T1,typename T2>booloperator==(const intrusive_ptr<T1> & lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T1,typename T2>booloperator==(const intrusive_ptr<T1> & lhs, T2 * rhs)noexcept;template<typename T1,typename T2>booloperator==(T1 * lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T1,typename T2>booloperator!=(const intrusive_ptr<T1> & lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T1,typename T2>booloperator!=(const intrusive_ptr<T1> & lhs, T2 * rhs)noexcept;template<typename T1,typename T2>booloperator!=(T1 * lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T1,typename T2>booloperator< (const intrusive_ptr<T1> & lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T1,typename T2>booloperator< (const intrusive_ptr<T1> & lhs, T2 * rhs)noexcept;template<typename T1,typename T2>booloperator< (T1 * lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T1,typename T2>booloperator> (const intrusive_ptr<T1> & lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T1,typename T2>booloperator> (const intrusive_ptr<T1> & lhs, T2 * rhs)noexcept;template<typename T1,typename T2>booloperator> (T1 * lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T1,typename T2>booloperator<=(const intrusive_ptr<T1> & lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T1,typename T2>booloperator<=(const intrusive_ptr<T1> & lhs, T2 * rhs)noexcept;template<typename T1,typename T2>booloperator<=(T1 * lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T1,typename T2>booloperator>=(const intrusive_ptr<T1> & lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T1,typename T2>booloperator>=(const intrusive_ptr<T1> & lhs, T2 * rhs)noexcept;template<typename T1,typename T2>booloperator>=(T1 * lhs,const intrusive_ptr<T2> & rhs)noexcept;template<typename T>voidswap(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>classintrusive_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;constexprintrusive_weak_ptr(nullptr_t =nullptr)noexcept;explicitintrusive_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();boolexpired()constnoexcept;longweak_count()constnoexcept;template<typename U = T> intrusive_ptr<U>lock()constnoexcept;voidreset(nullptr_t =nullptr)noexcept;voidreset(element_type * rhs);voidswap(intrusive_weak_ptr & rhs)noexcept;};template<typename T>booloperator==(const intrusive_weak_ptr<T> & lhs,const intrusive_weak_ptr<T> & rhs)constnoexcept;template<typename T>booloperator!=(const intrusive_weak_ptr<T> & lhs,const intrusive_weak_ptr<T> & rhs)constnoexcept;template<typename T>booloperator< (const intrusive_weak_ptr<T> & lhs,const intrusive_weak_ptr<T> & rhs)constnoexcept;template<typename T>booloperator> (const intrusive_weak_ptr<T> & lhs,const intrusive_weak_ptr<T> & rhs)constnoexcept;template<typename T>booloperator<=(const intrusive_weak_ptr<T> & lhs,const intrusive_weak_ptr<T> & rhs)constnoexcept;template<typename T>booloperator>=(const intrusive_weak_ptr<T> & lhs,const intrusive_weak_ptr<T> & rhs)constnoexcept;template<typename T>voidswap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)noexcept;}
T
andD
shall be complete types.intrusive_base<T, D>
shall be a public, non-ambiguous base ofT
.D
shall satisfy the requirements ofDefaultConstructible. None of the default constructor, the copy/move constructor, the copy/move assignment operator ofD
shall throw exceptions.
- Post-condition:
use_count() == 1
.
- Effects:
intrusive_base()
.
- Effects: No operation.
- Returns:
*this
.
- Effects: If
use_count() > 1
callsterminate()
.
- Returns: A reference to the stored deleter.
- Returns:
use_count() == 1
.
- Returns: The reference count of this object.
- Returns: The weak reference count of this object.
- Effects: Satisifies any allocation requests for resources that would be required if an
intrusive_weak_ptr
was to be constructed. Construction ofintrusive_weak_ptr
referring this object shall not throw any exceptions hereafter. - Throws:
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;
- Effects: Let
pu
be the result of conversion fromthis
to typecv U *
. Ifpu
is not null, increments the reference count ofpu
. - Returns:
intrusive_ptr<cv U>(pu)
. - Post-condition: If
pu
is not null,use_count()
is one greater than the value before the call.
- Returns:
intrusive_weak_ptr<cv U>(shared_from_this())
, as ifshared_from_this()
had never returned a null pointer. - Throws: Any exceptions that might be thrown by
reserve_weak()
. - Post-condition:
weak_count()
is one greater than the value before the call.
T
shall be a complete type.- Let
intrusive_base<T, D>
be a public, non-ambiguous base ofT
.deleter_type
is the template parameterD
. If no such base can be found, the program is ill-formed.
- Post-condition:
get() == nullptr
anduse_count() == 0
andweak_count() == 0
.
- Effects: If
rhs
is not null, increments the reference count of*rhs
. - Post-condition:
get() == rhs
. Ifrhs
is not null,rhs->use_count()
is one greater than the value before the call.
- Remarks: This constructor shall not participate in overload resolution unless
U *
is implicitly convertible toT *
andE
is implicitly convertible toD
. - Effects:
intrusive_ptr(rhs.release())
.
- Remarks: This constructor shall not participate in overload resolution unless
U *
is implicitly convertible toT *
. - Effects: If
rhs
is not null, increments the reference count of*rhs
. - Post-condition:
get() == rhs.get()
anduse_count() == rhs.use_count()
. Ifrhs.use_count()
is greater than zero before the call,use_count()
is one greater than that value.
- Remarks: This constructor shall not participate in overload resolution unless
U *
is implicitly convertible toT *
. - Post-condition:
get()
equals the value ofrhs.get()
before the call andrhs.get() == nullptr
.use_count()
equals the value ofrhs.use_count()
before the call andrhs.use_count() == 0
.
- Effects:
intrusive_ptr(rhs.get())
- Effects:
intrusive_ptr(rhs.release())
- Effects:
intrusive_ptr(rhs).swap(*this)
.
- Effects:
reset()
followed byrhs.swap(*this)
.
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());
- Returns: The stored pointer.
- Effects: Sets the stored pointer to
nullptr
without deleting any objects. - Returns: The value of
get()
before the call. - Post-condition:
get() == nullptr
.
- Returns: If
get()
is null,0
. Otherwise,get()->intrusive_base<T, D>::use_count()
.
- Returns: If
get()
is null,0
. Otherwise,get()->intrusive_base<T, D>::weak_count()
.
- Effects:
intrusive_ptr().swap(*this)
.
- Effects:
intrusive_ptr(rhs).swap(*this)
.
- Post-condition:
get()
equals the value ofrhs.get()
before the call andrhs.get()
equals the value ofget()
before the call.use_count()
equals the value ofrhs.use_count()
before the call andrhs.use_count()
equals the value ofuse_count()
before the call.
- Returns:
get() != nullptr
.
- Pre-condition:
get()
shall not be null. - Returns:
*get()
.
- Pre-condition:
get()
shall not be null. - Returns:
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;
- Returns:
lhs.get() == rhs.get()
,lhs.get() == rhs
andlhs == 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;
- Returns:
lhs.get() != rhs.get()
,lhs.get() != rhs
andlhs != 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;
- Returns:
lhs.get() < rhs.get()
,lhs.get() < rhs
andlhs < 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;
- Returns:
lhs.get() > rhs.get()
,lhs.get() > rhs
andlhs > 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;
- Returns:
lhs.get() <= rhs.get()
,lhs.get() <= rhs
andlhs <= 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;
- Returns:
lhs.get() >= rhs.get()
,lhs.get() >= rhs
andlhs >= rhs.get()
, respectively.
- Effects:
lhs.swap(rhs)
.
- Returns:
intrusive_ptr<T>(new T(forward<Args>(args)...))
.
template<typename U, typename T> intrusive_ptr<U> static_pointer_cast(intrusive_ptr<T> src) noexcept;
- Effects: Let
u
be the result ofstatic_cast<U *>(src.get())
. Callssrc.release()
. - Returns:
intrusive_ptr<U>(u)
.
template<typename U, typename T> intrusive_ptr<U> dynamic_pointer_cast(intrusive_ptr<T> src) noexcept;
- Effects: Let
u
be the result ofdynamic_cast<U *>(src.get())
. Ifu
is not null, callssrc.release()
. - Returns:
intrusive_ptr<U>(u)
.
template<typename U, typename T> intrusive_ptr<U> const_pointer_cast(intrusive_ptr<T> src) noexcept;
- Effects: Let
u
be the result ofconst_cast<U *>(src.get())
. Callssrc.release()
. - Returns:
intrusive_ptr<U>(u)
.
T
shall be a complete type.- Let
intrusive_base<T, D>
be a public, non-ambiguous base ofT
.deleter_type
is the template parameterD
. If no such base can be found, the program is ill-formed.
- Post-condition:
expired()
andweak_count() == 0
.
- Effects: If
rhs
is not null, increments the weak reference count of*rhs
. - Throws: Any exceptions that might be thrown by
rhs->reserve_weak()
. - Post-condition:
lock().get() == rhs
. Ifrhs
is not null,rhs->weak_count()
is one greater than the value before the call.
- Effects:
intrusive_weak_ptr(rhs.get())
.
- Remarks: This constructor shall not participate in overload resolution unless
U *
is implicitly convertible toT *
. - Effects: If
rhs.weak_count()
is greater than zero, increments the weak reference count of the object refered byrhs
, as if it had never expired. - Post-condition:
weak_count() == rhs.weak_count()
. Ifrhs.weak_count()
is greater than zero before the call,weak_count()
is one greater than that value.
- Remarks: This constructor shall not participate in overload resolution unless
U *
is implicitly convertible toT *
. - Post-condition:
weak_count()
equals the value ofrhs.weak_count()
before the call andrhs.weak_count() == 0
.
- Effects:
intrusive_weak_ptr(rhs.lock().get())
, as if the object referred byrhs
had never expired, if any.
- Effects:
intrusive_weak_ptr(rhs.lock().get())
thenrhs.reset()
, as if the object referred byrhs
had never expired, if any.
- Effects:
intrusive_weak_ptr(rhs).swap(*this)
.
- Effects:
reset()
followed byrhs.swap(*this)
.
- Effects: Let
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. Ifpt
is not null, decrements the weak reference count of*pt
.
- Effects: Let
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. - Returns: If
pt
is null,true
. Otherwise,pt->use_count() > 0
.
- Effects: Let
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. - Returns: If
pt
is null,0
. Otherwise,pt->weak_count()
.
- Effects: Atomically executes: Let
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. Letpu
be the result of conversion frompu
to typeU *
. Ifpu
is not null, increments the reference count ofpu
. - Returns:
intrusive_ptr<U>(pu)
. - Post-condition: If
pu
is not null,use_count()
is one greater thanpt->intrusive_base<T, D>::use_count()
before the call.
- Effects:
intrusive_weak_ptr().swap(*this)
.
- Effects:
intrusive_weak_ptr(rhs).swap(*this)
.
- Post-condition:
lock()
equals the value ofrhs.lock()
before the call andrhs.lock()
equals the value oflock()
before the call.weak_count()
equals the value ofrhs.weak_count()
before the call andrhs.weak_count()
equals the value ofweak_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;
- Remarks: These functions define an otherwise unspecified strick weak ordering of
intrusive_weak_ptr
, enabling use ofintrusive_weak_ptr
in associative containers.
- Effects:
lhs.swap(rhs)
.
About
Proposal for std::intrusive_ptr
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
No releases published
Packages0
No packages published
Contributors2
Uh oh!
There was an error while loading.Please reload this page.