Skip to content

Latest commit

 

History

History
126 lines (89 loc) · 6.62 KB

intrusive_shared_ptr.md

File metadata and controls

126 lines (89 loc) · 6.62 KB

Header <intrusive_shared_ptr/intrusive_shared_ptr.h>

Class isptr::intrusive_shared_ptr

template<class T, class Traits>
class ISPTR_TRIVIAL_ABI intrusive_shared_ptr;

Macro ISPTR_TRIVIAL_ABI expands to [[clang::trivial_abi]] when compiled under clang.

Traits requirements

Traits must expose two static methods with the following signatures:

<unspecified> add_ref(T *) noexcept
<unspecified> sub_ref(T *) noexcept

Return value of either method is ignored. The argument is never nullptr.

Namespace Types

  • template<class Traits, class T> constexpr bool are_intrusive_shared_traits checks whether given Traits satisfy the traits requirements above for the given type T.
  • template<class T> using is_intrusive_shared_ptr = ... type trait that is std::true_type or std::false_type depending on whether T is a valid intrusive_shared_ptr type.
  • template<class T> bool constexpr is_intrusive_shared_ptr_v = is_intrusive_shared_ptr<T>::value;

Nested Types

using pointer = T *;
using element_type = T;
using traits_type = Traits;

Operations

Construction/assignment/destruction

  • Default constructor. noexcept, produces a null pointer

  • Constructor from nullptr. Same as above

  • Copy constructor. noexcept. Accepts:

    • Objects of the same type and traits
    • Objects that point to Y such as Y * is convertible to T * using the same or different traits.
  • Move constructor. noexcept. Accepts:

    • Objects of the same type and traits. No changes to reference count are performed.
    • Objects that point to Y such as Y * is convertible to T * using the same or different traits. If the source and destination traits are the same no changes to source reference count are performed.
  • Copy assignment. noexcept. Accepts:

    • Objects of the same type and traits
    • Objects that point to Y such as Y * is convertible to T * using the same or different traits.
  • Move assignment. noexcept. Accepts:

    • Objects of the same type and traits
    • Objects that point to Y such as Y * is convertible to T * using the same or different traits. If the source and destination traits are the same no changes to source reference count are performed.
  • Destructor. noexcept. Non-virtual.

  • static intrusive_shared_ptr<T, Traits> noref() noexcept Creates a smart pointer from a raw pointer without modifying the reference count.

  • static intrusive_shared_ptr<T, Traits> ref() noexcept Creates a smart pointer from a raw pointer and increments reference count.

Instance methods

  • T * get() const noexcept Returns the stored pointer. Reference count is not modified.
  • T * operator->() const noexcept Returns the stored pointer. Reference count is not modified.
  • T & operator*() const noexcept Returns the reference to pointee. Undefined if stored pointer is nullptr
  • template<class M> M & operator->*(M T::*memptr) const noexcept Returns the result of 'stored pointer'->*memptr This allows access via pointee's pointer to members
  • explicit operator bool() const noexcept true if the pointer is non null
  • output_param get_output_param() noexcept returns a temporary object that exposes operator T**() && noexcept. This can be passed as an output parameter to C functions that return a reference counted pointer. The destructor of the temporary will fill this pointer with the returned result.
  • T * release() noexcept Releases the stored pointer. The object is set to null and calling code assumes ownership of the pointer. No adjustment is made to the reference count.
  • void reset() noexcept Clears the stored pointer. The reference count is decremented.
  • void swap(intrusive_shared_ptr<T, Traits> & other) noexcept and
    friend void swap(intrusive_shared_ptr<T, Traits> & lhs, intrusive_shared_ptr<T, Traits> & rhs) noexcept (ADL only) Perform swap of pointers of the same type

Namespace methods

  • Equality: ==, !=. All noexcept. Work between intrusive_shared_ptr of compatible types and any traits as well as raw pointers and nullptr.

  • Comparisons: <, <=, >=, >. All noexcept. On C++20 these are replaced by <=>. Work between intrusive_shared_ptr of compatible types and any traits as well as raw pointers.

  • Namespace method: template<class Char> friend std::basic_ostream<Char> & operator<<(std::basic_ostream<Char> & str, const intrusive_shared_ptr<T, Traits> & ptr) (ADL only) outputs the stored pointer value to a stream

  • Dest intrusive_const_cast<Dest>(intrusive_shared_ptr src) noexcept. Performs an equivalent of const_cast on passed argument. The destination type needs to be a valid intrusive_shared_ptr type whose underlying type is convertible from source's via const_cast.

  • Dest intrusive_static_cast<Dest>(intrusive_shared_ptr src) noexcept. Performs an equivalent of static_cast on passed argument. The destination type needs to be a valid intrusive_shared_ptr type whose underlying type is convertible from source's via static_cast.

  • Dest intrusive_dynamic_cast<Dest>(intrusive_shared_ptr src) noexcept. Performs an equivalent of dynamic_cast on passed argument. The destination type needs to be a valid intrusive_shared_ptr type whose underlying type is convertible from source's via dynamic_cast. Returns a null result if underlying dynamic_cast fails.

Class std::atomic<isptr::intrusive_shared_ptr>

Provides the standard set of std::atomic functionality:

  • using value_type = isptr::intrusive_shared_ptr<T, Traits>
  • static constexpr bool is_always_lock_free
  • constexpr atomic() noexcept. Initializes with null pointer.
  • atomic(value_type desired) noexcept
  • atomic(const atomic&) = delete Deleted!
  • void operator=(const atomic&) = delete Deleted!
  • ~atomic() noexcept
  • void operator=(value_type desired) noexcept
  • operator value_type() const noexcept
  • value_type load(memory_order order = memory_order_seq_cst) const noexcept
  • void store(value_type desired, memory_order order = memory_order_seq_cst) noexcept
  • value_type exchange(value_type desired, memory_order order = memory_order_seq_cst) noexcept
  • bool compare_exchange_strong(value_type & expected, value_type desired, memory_order success, memory_order failure) noexcept
  • bool compare_exchange_strong(value_type & expected, value_type desired, memory_order order = memory_order_seq_cst) noexcept
  • bool compare_exchange_weak(value_type & expected, value_type desired, memory_order success, memory_order failure) noexcept
  • bool compare_exchange_weak(value_type & expected, value_type desired, memory_order order = memory_order_seq_cst) noexcept
  • bool is_lock_free() const noexcept