Intrusive Smart Pointer#
#include <dplx/cncr/intrusive_ptr.hpp>
namespace dplx::cncr {}
Concepts#
-
template<typename RC>
concept ref_counted# A type whose lifetime is managed by an internal reference counter and which has a
reference_counted_traits
specialization for controlling the reference counter.All functions are required to be
noexcept
.Notation
Valid Expressions
reference_counted_traits<RC>::counter_type is the underlying integer type or void if unknown.
reference_counted_traits<RC>::add_reference(obj) increments obj’s reference count by one.
reference_counted_traits<RC>::release(obj) decrements obj’s reference count by one and atomically destructs it if the reference count reached zero.
-
template<typename RC>
concept inspectable_ref_counted# Requires that a
ref_counted
type also provides a way to get an estimate of the current reference count. Not requiring the value to be excact allows reference counted objects shared across multiple threads to satisfy this.The only value required to be stable is
1
in which case our thread should be the only pointee. (With the exception of insane software architectures which retain non owning across threads).All functions are required to be
noexcept
.Notation
Valid Expressions
reference_counted_traits<RC>::counter_type is the underlying integer type.
reference_counted_traits<RC>::reference_count(obj) returns an (estimate) of the current counter value of type
counter_type
.
-
template<ref_counted RC>
concept detail::dplx_ref_counted# Exposition Only
Describes the typical deeplex reference counting API.
All functions are required to be
noexcept
.Notation
Valid Expressions
Customization Points#
-
template<typename RC>
class reference_counted_traits# This is a customization point i.e. there is no primary template definition.
The implementation requirements are described by the
ref_counted
andinspectable_ref_counted
concepts.
-
template<detail::dplx_ref_counted RC>
class reference_counted_traits<RC># The specialization of
reference_counted_traits
for types satisfyingdetail::dplx_ref_counted
.The specialization satisfies
inspectable_ref_counted
.
Factory Functions#
-
template<ref_counted RC>
constexpr auto intrusive_ptr_import(RC *obj) -> intrusive_ptr<RC># Creates a intrusive_ptr<RC> tracking obj assuming ownership of an existing reference (i.e. it doesn’t call
add_reference()
)It is a type deducing wrapper around intrusive_ptr<RC>::import.
-
template<ref_counted RC>
constexpr auto intrusive_ptr_acquire(RC *obj) -> intrusive_ptr<RC># Creates a intrusive_ptr<RC> tracking obj assuming ownership by acquiring a new reference (i.e. it calls
add_reference()
).It is a type deducing wrapper around intrusive_ptr<RC>::acquire.
Types#
-
template<ref_counted RC>
class intrusive_ptr<RC, RC># The usual intrusive smart pointer which poses as a pointer to the object whose lifetime it manages.
The type satisfies std::regular, i.e. it is default initializable, copyable and equality comparable. It is also swappable, totally ordered and contextually convertible to bool.
Additionally the following members exist:
-
using handle_type = intrusive_ptr<RC>#
Exposes the type which is used for reference counting. It is exposed for compatibility with the aliasing variant
intrusive_ptr<T, RC>
whose element_type is not equal to RC.
-
constexpr intrusive_ptr(std::nullptr_t) noexcept#
Constructs an empty instance from a nullptr literal which makes the following expressions well formed:
intrusive_ptr<T> ptr{nullptr}; ptr = nullptr;
-
template<ref_counted U>
constexpr intrusive_ptr(intrusive_ptr<U> &&other) noexcept# Imports ownership from a compatible intrusive_ptr<U> instance.
This constructor is only available if std::convertible_to<U*, RC*> holds.
-
template<ref_counted U>
constexpr intrusive_ptr(intrusive_ptr<U> const &other) noexcept# Aquires ownership from a compatible intrusive_ptr<U> instance.
This constructor is only available if std::convertible_to<U*, RC*> holds.
-
static constexpr auto import(RC *ptr) noexcept -> intrusive_ptr<RC>#
Creates a intrusive_ptr<RC> tracking ptr assuming ownership of an existing reference (i.e. it doesn’t call
add_reference()
).
-
static constexpr auto acquire(RC *ptr) noexcept -> intrusive_ptr<RC>#
Creates a intrusive_ptr<RC> tracking ptr assuming ownership by acquiring a new reference (i.e. it calls
add_reference()
).
-
constexpr auto get_handle() const noexcept -> intrusive_ptr<RC>#
Returns a copy of
this
. It is exposed for compatibility with the aliasing variantintrusive_ptr<T, RC>
whose element_type is not equal to RC.
-
constexpr auto use_count() const noexcept -> reference_counted_traits<RC>::counter_type#
-
constexpr auto reference_count() const noexcept -> reference_counted_traits<RC>::counter_type#
If RC satisfies
inspectable_ref_counted
it returns the (approximate) number of references. The only value guaranteed to be stable in multi-threaded environments is1
.The
use_count()
name exists for API compatibility withstd::shared_ptr
.
-
using handle_type = intrusive_ptr<RC>#
-
template<>
class intrusive_ptr<void, void># A type erased intrusive pointer. It keeps a pointer to a vtable in addition to a void * referencing the bound object.
The type satisfies std::regular, i.e. it is default initializable, copyable and equality comparable. It is also swappable, totally ordered and contextually convertible to bool.
You can either (copy) assign normal intrusive pointer instances or use the static class functions
import
oracquire
Additionally the following members exist:
-
using element_type = void#
Exposes the type parameter for meta programming purposes.
-
using handle_type = intrusive_ptr<void, void>#
Exposes the type which is used for reference counting. It is exposed for compatibility with the aliasing variant
intrusive_ptr<T, RC>
whose element_type is not equal to void.
-
intrusive_ptr(std::nullptr_t) noexcept#
Constructs an empty instance from a nullptr literal which makes the following expressions well formed:
intrusive_ptr<void> ptr{nullptr}; ptr = nullptr;
-
template<ref_counted U>
intrusive_ptr(intrusive_ptr<U> &&other) noexcept# Imports ownership from an intrusive_ptr<U> instance.
-
template<ref_counted U>
intrusive_ptr(intrusive_ptr<U> const &other) noexcept# Aquires ownership from an intrusive_ptr<U> instance.
-
template<ref_counted RC>
static auto import(RC *ptr) noexcept -> intrusive_ptr<void, void># Creates a intrusive_ptr<void, void> tracking ptr assuming ownership of an existing reference (i.e. it doesn’t call
add_reference()
).
-
template<ref_counted RC>
static auto acquire(RC *ptr) noexcept -> intrusive_ptr<void, void># Creates a intrusive_ptr<void, void> tracking ptr assuming ownership by acquiring a new reference (i.e. it calls
add_reference()
).
-
auto get() const noexcept -> void*#
Retrieves the stored object pointer.
-
auto get_handle() const noexcept -> intrusive_ptr<void>#
Returns a copy of
this
. It is exposed for compatibility with the aliasing variantintrusive_ptr<T, RC>
whose element_type is not equal to void.
-
template<ref_counted U>
auto release_as() noexcept -> U*# Returns the bound object pointer after casting it to U after unbinding
this
without decrementing the reference counter.
-
using element_type = void#
-
template<typename T, ref_counted RC = T>
class intrusive_ptr# The main template is an aliasing intrusive pointer which means it poses as a pointer to an object of type T while managing the reference count of (a potentially different) object of type RC.
The type satisfies std::regular, i.e. it is default initializable, copyable and equality comparable. It is also swappable, totally ordered and contextually convertible to bool.
Additionally the following members exist:
-
using handle_type = intrusive_ptr<RC>#
Exposes the intrusive pointer type which implements reference counting.
-
constexpr intrusive_ptr(std::nullptr_t) noexcept#
Constructs an empty instance from a nullptr literal which makes the following expressions well formed:
intrusive_ptr<T, RC> ptr{nullptr}; ptr = nullptr;
-
constexpr intrusive_ptr(intrusive_ptr<RC> &&handle, T *ptr) noexcept#
Creates a intrusive_ptr<T, RC> tracking handle assuming ownership of an existing reference (i.e. it doesn’t call
add_reference()
).The constructed intrusive pointer poses as ptr afterwards.
-
constexpr intrusive_ptr(intrusive_ptr<RC> const &handle, T *ptr) noexcept#
Creates a intrusive_ptr<T, RC> tracking handle assuming ownership by acquiring a new reference (i.e. it calls
add_reference()
).The constructed intrusive pointer poses as ptr afterwards.
-
constexpr auto get_handle() const noexcept -> intrusive_ptr<RC>#
Returns a copy of the contained object handle.
-
constexpr auto use_count() const noexcept -> reference_counted_traits<RC>::counter_type#
-
constexpr auto reference_count() const noexcept -> reference_counted_traits<RC>::counter_type#
If RC satisfies
inspectable_ref_counted
it returns the (approximate) number of references. The only value guaranteed to be stable in multi-threaded environments is1
.The
use_count()
name exists for API compatibility withstd::shared_ptr
.
-
using handle_type = intrusive_ptr<RC>#