Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Proposal for std::intrusive_ptr

License

NotificationsYou must be signed in to change notification settings

lhmouse/intrusive_ptr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Synopsis

#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;}

template<typename T, class D> class intrusive_base

In general
  • 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.
constexpr intrusive_base() noexcept;
  • Post-condition:use_count() == 1.
constexpr intrusive_base(const intrusive_base & rhs) noexcept;
  • Effects:intrusive_base().
intrusive_base & operator=(const intrusive_base & rhs) noexcept;
  • Effects: No operation.
  • Returns:*this.
~intrusive_base();
  • Effects: Ifuse_count() > 1 callsterminate().
const deleter_type & get_deleter() const noexcept;
deleter_type & get_deleter() noexcept;
  • Returns: A reference to the stored deleter.
bool unique() const volatile noexcept;
  • Returns:use_count() == 1.
long use_count() const volatile noexcept;
  • Returns: The reference count of this object.
long weak_count() const volatile noexcept;
  • Returns: The weak reference count of this object.
void reserve_weak() const volatile;
  • Effects: Satisifies any allocation requests for resources that would be required if anintrusive_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;
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;
  • Effects: Letpu 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: Ifpu 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();
  • 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 byreserve_weak().
  • Post-condition:weak_count() is one greater than the value before the call.

template<typename T> class intrusive_ptr

In general
  • T shall be a complete type.
  • Letintrusive_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.
constexpr intrusive_ptr(nullptr_t = nullptr) noexcept;
  • Post-condition:get() == nullptr anduse_count() == 0 andweak_count() == 0.
explicit constexpr intrusive_ptr(element_type * rhs) noexcept;
  • Effects: Ifrhs 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.
template<typename U, typename E> intrusive_ptr(unique_ptr<U, E> && rhs) noexcept;
  • Remarks: This constructor shall not participate in overload resolution unlessU * is implicitly convertible toT * andE is implicitly convertible toD.
  • Effects:intrusive_ptr(rhs.release()).
template<typename U> intrusive_ptr(const intrusive_ptr<U> & rhs) noexcept;
  • Remarks: This constructor shall not participate in overload resolution unlessU * is implicitly convertible toT *.
  • Effects: Ifrhs 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.
template<typename U> intrusive_ptr(intrusive_ptr<U> && rhs) noexcept;
  • Remarks: This constructor shall not participate in overload resolution unlessU * 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.
intrusive_ptr(const intrusive_ptr & rhs) noexcept;
  • Effects:intrusive_ptr(rhs.get())
intrusive_ptr(intrusive_ptr && rhs) noexcept;
  • Effects:intrusive_ptr(rhs.release())
intrusive_ptr & operator=(const intrusive_ptr & rhs) noexcept;
  • Effects:intrusive_ptr(rhs).swap(*this).
intrusive_ptr & operator=(intrusive_ptr && rhs) noexcept;
  • Effects:reset() followed byrhs.swap(*this).
~intrusive_ptr();
  • Effects: Ifget() 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;
  • Returns: The stored pointer.
element_type * release() noexcept;
  • Effects: Sets the stored pointer tonullptr without deleting any objects.
  • Returns: The value ofget() before the call.
  • Post-condition:get() == nullptr.
long use_count() const noexcept;
  • Returns: Ifget() is null,0. Otherwise,get()->intrusive_base<T, D>::use_count().
long weak_count() const noexcept;
  • Returns: Ifget() is null,0. Otherwise,get()->intrusive_base<T, D>::weak_count().
void reset(nullptr_t = nullptr) noexcept;
  • Effects:intrusive_ptr().swap(*this).
void reset(element_type * rhs) noexcept;
  • Effects:intrusive_ptr(rhs).swap(*this).
void swap(intrusive_ptr & rhs) noexcept;
  • 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.
explicit constexpr operator bool() const noexcept;
  • Returns:get() != nullptr.
element_type & operator*() const;
  • Pre-condition:get() shall not be null.
  • Returns:*get().
element_type * operator->() const;
  • 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.
template<typename T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) noexcept;
  • Effects:lhs.swap(rhs).
template<typename T, typename ... Args> intrusive_ptr<T> make_intrusive(Args &&... args);
  • 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: Letu 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: Letu 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: Letu be the result ofconst_cast<U *>(src.get()). Callssrc.release().
  • Returns:intrusive_ptr<U>(u).

template<typename T> class intrusive_weak_ptr

In general
  • T shall be a complete type.
  • Letintrusive_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.
constexpr intrusive_weak_ptr(nullptr_t = nullptr) noexcept;
  • Post-condition:expired() andweak_count() == 0.
explicit intrusive_weak_ptr(element_type * rhs);
  • Effects: Ifrhs is not null, increments the weak reference count of*rhs.
  • Throws: Any exceptions that might be thrown byrhs->reserve_weak().
  • Post-condition:lock().get() == rhs. Ifrhs is not null,rhs->weak_count() is one greater than the value before the call.
intrusive_weak_ptr(const intrusive_ptr<T> & rhs);
  • Effects:intrusive_weak_ptr(rhs.get()).
template<typename U> intrusive_weak_ptr(const intrusive_weak_ptr<U> & rhs) noexcept;
  • Remarks: This constructor shall not participate in overload resolution unlessU * is implicitly convertible toT *.
  • Effects: Ifrhs.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.
template<typename U> intrusive_weak_ptr(intrusive_weak_ptr<U> && rhs) noexcept;
  • Remarks: This constructor shall not participate in overload resolution unlessU * is implicitly convertible toT *.
  • Post-condition:weak_count() equals the value ofrhs.weak_count() before the call andrhs.weak_count() == 0.
intrusive_weak_ptr(const intrusive_weak_ptr & rhs) noexcept;
  • Effects:intrusive_weak_ptr(rhs.lock().get()), as if the object referred byrhs had never expired, if any.
intrusive_weak_ptr(intrusive_weak_ptr && rhs) noexcept;
  • Effects:intrusive_weak_ptr(rhs.lock().get()) thenrhs.reset(), as if the object referred byrhs had never expired, if any.
intrusive_weak_ptr & operator=(const intrusive_weak_ptr & rhs) noexcept;
  • Effects:intrusive_weak_ptr(rhs).swap(*this).
intrusive_weak_ptr & operator=(intrusive_weak_ptr && rhs) noexcept;
  • Effects:reset() followed byrhs.swap(*this).
~intrusive_weak_ptr();
  • Effects: Letpt 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.
bool expired() const noexcept;
  • Effects: Letpt 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: Ifpt is null,true. Otherwise,pt->use_count() > 0.
long weak_count() const noexcept;
  • Effects: Letpt 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: Ifpt is null,0. Otherwise,pt->weak_count().
template<typename U = T> intrusive_ptr<U> lock() const noexcept;
  • Effects: Atomically executes: Letpt 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: Ifpu is not null,use_count() is one greater thanpt->intrusive_base<T, D>::use_count() before the call.
void reset(nullptr_t = nullptr) noexcept;
  • Effects:intrusive_weak_ptr().swap(*this).
void reset(element_type * rhs);
  • Effects:intrusive_weak_ptr(rhs).swap(*this).
void swap(intrusive_weak_ptr & rhs) noexcept;
  • 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 ofintrusive_weak_ptr, enabling use ofintrusive_weak_ptr in associative containers.
template<typename T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs) noexcept;
  • Effects:lhs.swap(rhs).

Releases

No releases published

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp