Helios Engine
A modular ECS based data-oriented C++23 game engine framework
Loading...
Searching...
No Matches
helios::mem::RefCounted< Derived, Allocator > Class Template Reference

Non-atomic intrusive reference-counted smart pointer. More...

#include <ref_counted.hpp>

Public Types

using AllocatorType = Allocator

Public Member Functions

constexpr RefCounted () noexcept=default
 Constructs a null handle.
constexpr RefCounted (AllocatorType alloc) noexcept
 Constructs a null handle storing a pre-built allocator.
constexpr RefCounted (std::nullptr_t) noexcept
 Constructs a null handle explicitly (default-constructible allocators only).
constexpr RefCounted (std::nullptr_t, AllocatorType alloc) noexcept
 Constructs a null handle explicitly with an explicit allocator.
constexpr RefCounted (std::pmr::memory_resource *resource) noexcept
 Constructs a null handle with a PMR memory resource.
 RefCounted (Derived *ptr, std::pmr::memory_resource *resource) noexcept
 Constructs from a raw pointer, taking ownership, with a PMR memory resource.
 RefCounted (Derived *ptr, AllocatorType alloc) noexcept
 Constructs from a raw pointer, taking ownership, with an explicit allocator.
 RefCounted (Derived *ptr) noexcept
 Constructs from a raw pointer using a default-constructed allocator.
 RefCounted (const RefCounted &other) noexcept
 Copy-constructs a handle sharing ownership with other.
 RefCounted (RefCounted &&other) noexcept
 Move-constructs a handle transferring ownership from other.
template<typename Other>
requires std::convertible_to<Other*, Derived*>
 RefCounted (const RefCounted< Other, Allocator > &other) noexcept
 Converting copy constructor from a compatible (derived) type.
template<typename Other>
requires std::convertible_to<Other*, Derived*>
 RefCounted (RefCounted< Other, Allocator > &&other) noexcept
 Converting move constructor from a compatible (derived) type.
 ~RefCounted () noexcept
 Destroys the handle and decrements the reference count.
RefCountedoperator= (const RefCounted &other) noexcept
 Copy-assigns shared ownership from other.
RefCountedoperator= (RefCounted &&other) noexcept
 Move-assigns ownership from other.
template<typename Other>
requires std::convertible_to<Other*, Derived*>
RefCountedoperator= (const RefCounted< Other, Allocator > &other) noexcept
 Converting copy-assignment from a compatible (derived) handle.
template<typename Other>
requires std::convertible_to<Other*, Derived*>
RefCountedoperator= (RefCounted< Other, Allocator > &&other) noexcept
 Converting move-assignment from a compatible (derived) handle.
RefCountedoperator= (std::nullptr_t) noexcept
 Assigns null, releasing any currently managed object.
void Reset () noexcept
 Releases ownership and resets the handle to null.
Derived * Release () noexcept
 Releases ownership without decrementing the ref count.
Derived & operator* () const noexcept
 Dereferences the managed object.
Derived * operator-> () const noexcept
 Accesses the managed object through pointer syntax.
 operator bool () const noexcept
 Checks whether the handle owns an object.
bool operator== (const RefCounted &other) const noexcept
 Compares handle identity by managed pointer address.
bool operator== (std::nullptr_t) const noexcept
 Checks whether the handle is null.
template<typename Other>
bool operator== (const RefCounted< Other, Allocator > &other) const noexcept
 Compares handle identity against a compatible derived handle.
bool Unique () const noexcept
 Checks if this handle is the sole owner of the managed object.
bool Empty () const noexcept
 Checks if the handle is null.
Derived * Get () const noexcept
 Returns the raw pointer without releasing ownership.
uint32_t RefCount () const noexcept
 Returns the current reference count.
const AllocatorTypeGetAllocator () const noexcept
 Returns a reference to the stored allocator.
template<typename Other>
requires std::convertible_to<Other*, Derived*>
RefCounted< Derived, Allocator > & operator= (const RefCounted< Other, Allocator > &other) noexcept
template<typename Other>
requires std::convertible_to<Other*, Derived*>
RefCounted< Derived, Allocator > & operator= (RefCounted< Other, Allocator > &&other) noexcept

Detailed Description

template<typename Derived, typename Allocator>
requires std::derived_from<Derived, RcFromThis<Derived>>
class helios::mem::RefCounted< Derived, Allocator >

Non-atomic intrusive reference-counted smart pointer.

Manages the lifetime of an object that inherits from RcFromThis<T>. The reference counter lives inside the object itself (no separate control block).

Semantics are similar to std::shared_ptr but:

  • No heap allocation for the control block.
  • NOT thread-safe. Use AtomicRefCounted / Arc for shared ownership across threads.
  • The managed object MUST inherit from RcFromThis<T>.
Note
A null RefCounted<T> is valid and comparable.
Warning
Not thread-safe. Do NOT share a single RefCounted<T> instance across threads. Each thread must hold its own copy of the handle.
Template Parameters
DerivedConcrete type managed by this handle; must inherit RcFromThis<Derived>
AllocatorAllocator type used for construction and destruction of the managed object (defaults to std::allocator<Derived>)
// Default allocator
auto mesh = helios::mem::MakeRc<Mesh>(42);
// Custom pool allocator
auto copy = mesh; // ref count: 2
mesh.Reset(); // ref count: 1
copy.Reset(); // ref count: 0 → Mesh deleted via
Lock-free PMR pool allocator for fixed-size blocks.
auto MakeRc(Args &&... args) -> Rc< T >
Allocates and constructs a T object, returning a Rc<T, std::allocator<T>> handle.

Definition at line 230 of file ref_counted.hpp.

Member Typedef Documentation

◆ AllocatorType

template<typename Derived, typename Allocator>
using helios::mem::RefCounted< Derived, Allocator >::AllocatorType = Allocator

Definition at line 232 of file ref_counted.hpp.

Constructor & Destructor Documentation

◆ RefCounted() [1/12]

template<typename Derived, typename Allocator>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( )
constexprdefaultnoexcept

Constructs a null handle.

Note
Only available when AllocatorType is default-constructible. For stateful allocators, use RefCounted(AllocatorType) or MakeRcWith.

◆ RefCounted() [2/12]

template<typename Derived, typename Allocator>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( AllocatorType alloc)
inlineexplicitconstexprnoexcept

Constructs a null handle storing a pre-built allocator.

Use this when the allocator is stateful and you need a typed null handle that is ready to receive an assignment from a MakeRcWith-created handle.

Definition at line 249 of file ref_counted.hpp.

◆ RefCounted() [3/12]

template<typename Derived, typename Allocator>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( std::nullptr_t )
inlineexplicitconstexprnoexcept

Constructs a null handle explicitly (default-constructible allocators only).

Definition at line 254 of file ref_counted.hpp.

◆ RefCounted() [4/12]

template<typename Derived, typename Allocator>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( std::nullptr_t ,
AllocatorType alloc )
inlineconstexprnoexcept

Constructs a null handle explicitly with an explicit allocator.

Definition at line 259 of file ref_counted.hpp.

◆ RefCounted() [5/12]

template<typename Derived, typename Allocator>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( std::pmr::memory_resource * resource)
inlineexplicitconstexprnoexcept

Constructs a null handle with a PMR memory resource.

Only available when AllocatorType is std::pmr::polymorphic_allocator<T>.

Parameters
resourcePolymorphic memory resource to use for allocations

Definition at line 268 of file ref_counted.hpp.

◆ RefCounted() [6/12]

template<typename Derived, typename Allocator>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( Derived * ptr,
std::pmr::memory_resource * resource )
inlinenoexcept

Constructs from a raw pointer, taking ownership, with a PMR memory resource.

Only available when AllocatorType is std::pmr::polymorphic_allocator<T>.

Parameters
ptrRaw pointer to take ownership of (may be nullptr)
resourcePolymorphic memory resource to use for destruction

Definition at line 281 of file ref_counted.hpp.

◆ RefCounted() [7/12]

template<typename Derived, typename Allocator>
requires std::derived_from<Derived, RcFromThis<Derived>>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( Derived * ptr,
AllocatorType alloc )
inlinenoexcept

Constructs from a raw pointer, taking ownership, with an explicit allocator.

Warning
The pointer must have been allocated with the same allocator and must not be managed by any other owning handle at the time of this call.
Parameters
ptrRaw pointer to take ownership of (may be nullptr)
allocAllocator instance to use for destruction

Definition at line 498 of file ref_counted.hpp.

◆ RefCounted() [8/12]

template<typename Derived, typename Allocator>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( Derived * ptr)
inlineexplicitnoexcept

Constructs from a raw pointer using a default-constructed allocator.

Note
Only available when AllocatorType is default-constructible.

Definition at line 300 of file ref_counted.hpp.

◆ RefCounted() [9/12]

template<typename Derived, typename Allocator>
requires std::derived_from<Derived, RcFromThis<Derived>>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( const RefCounted< Derived, Allocator > & other)
inlinenoexcept

Copy-constructs a handle sharing ownership with other.

Parameters
otherHandle to copy from

Definition at line 508 of file ref_counted.hpp.

◆ RefCounted() [10/12]

template<typename Derived, typename Allocator>
requires std::derived_from<Derived, RcFromThis<Derived>>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( RefCounted< Derived, Allocator > && other)
inlinenoexcept

Move-constructs a handle transferring ownership from other.

Parameters
otherHandle to move from; left null after the operation

Definition at line 520 of file ref_counted.hpp.

◆ RefCounted() [11/12]

template<typename Derived, typename Allocator>
requires std::convertible_to<Other*, Derived*>
template<typename Other>
requires std::convertible_to<Other*, Derived*>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( const RefCounted< Other, Allocator > & other)
inlinenoexcept

Converting copy constructor from a compatible (derived) type.

Template Parameters
OtherType convertible to Derived*
Parameters
otherHandle to copy from

Definition at line 529 of file ref_counted.hpp.

◆ RefCounted() [12/12]

template<typename Derived, typename Allocator>
requires std::convertible_to<Other*, Derived*>
template<typename Other>
requires std::convertible_to<Other*, Derived*>
helios::mem::RefCounted< Derived, Allocator >::RefCounted ( RefCounted< Other, Allocator > && other)
inlinenoexcept

Converting move constructor from a compatible (derived) type.

Template Parameters
OtherType convertible to Derived*
Parameters
otherHandle to move from

Definition at line 543 of file ref_counted.hpp.

◆ ~RefCounted()

template<typename Derived, typename Allocator>
helios::mem::RefCounted< Derived, Allocator >::~RefCounted ( )
inlinenoexcept

Destroys the handle and decrements the reference count.

Definition at line 341 of file ref_counted.hpp.

Member Function Documentation

◆ Empty()

template<typename Derived, typename Allocator>
bool helios::mem::RefCounted< Derived, Allocator >::Empty ( ) const
inlinenodiscardnoexcept

Checks if the handle is null.

Returns
true if no object is managed

Definition at line 458 of file ref_counted.hpp.

◆ Get()

template<typename Derived, typename Allocator>
Derived * helios::mem::RefCounted< Derived, Allocator >::Get ( ) const
inlinenodiscardnoexcept

Returns the raw pointer without releasing ownership.

Returns
Raw pointer, or nullptr if the handle is null

Definition at line 464 of file ref_counted.hpp.

◆ GetAllocator()

template<typename Derived, typename Allocator>
const AllocatorType & helios::mem::RefCounted< Derived, Allocator >::GetAllocator ( ) const
inlinenodiscardnoexcept

Returns a reference to the stored allocator.

Returns
The allocator instance used for this handle

Definition at line 479 of file ref_counted.hpp.

◆ operator bool()

template<typename Derived, typename Allocator>
helios::mem::RefCounted< Derived, Allocator >::operator bool ( ) const
inlineexplicitnodiscardnoexcept

Checks whether the handle owns an object.

Returns
True when non-null, false otherwise

Definition at line 415 of file ref_counted.hpp.

◆ operator*()

template<typename Derived, typename Allocator>
requires std::derived_from<Derived, RcFromThis<Derived>>
Derived & helios::mem::RefCounted< Derived, Allocator >::operator* ( ) const
inlinenodiscardnoexcept

Dereferences the managed object.

Warning
Triggers assertion when the handle is null.
Returns
Reference to the managed object

Definition at line 641 of file ref_counted.hpp.

◆ operator->()

template<typename Derived, typename Allocator>
requires std::derived_from<Derived, RcFromThis<Derived>>
Derived * helios::mem::RefCounted< Derived, Allocator >::operator-> ( ) const
inlinenodiscardnoexcept

Accesses the managed object through pointer syntax.

Warning
Triggers assertion when the handle is null.
Returns
Pointer to the managed object

Definition at line 648 of file ref_counted.hpp.

◆ operator=() [1/7]

template<typename Derived, typename Allocator>
requires std::derived_from<Derived, RcFromThis<Derived>>
RefCounted< Derived, Allocator > & helios::mem::RefCounted< Derived, Allocator >::operator= ( const RefCounted< Derived, Allocator > & other)
inlinenoexcept

Copy-assigns shared ownership from other.

Parameters
otherHandle to copy from
Returns
Reference to this handle

Definition at line 550 of file ref_counted.hpp.

◆ operator=() [2/7]

template<typename Derived, typename Allocator>
template<typename Other>
requires std::convertible_to<Other*, Derived*>
RefCounted< Derived, Allocator > & helios::mem::RefCounted< Derived, Allocator >::operator= ( const RefCounted< Other, Allocator > & other)
inlinenoexcept

Definition at line 586 of file ref_counted.hpp.

◆ operator=() [3/7]

template<typename Derived, typename Allocator>
template<typename Other>
requires std::convertible_to<Other*, Derived*>
RefCounted & helios::mem::RefCounted< Derived, Allocator >::operator= ( const RefCounted< Other, Allocator > & other)
noexcept

Converting copy-assignment from a compatible (derived) handle.

Template Parameters
OtherType convertible to Derived*
Parameters
otherHandle to copy from
Returns
Reference to this handle

◆ operator=() [4/7]

template<typename Derived, typename Allocator>
requires std::derived_from<Derived, RcFromThis<Derived>>
RefCounted< Derived, Allocator > & helios::mem::RefCounted< Derived, Allocator >::operator= ( RefCounted< Derived, Allocator > && other)
inlinenoexcept

Move-assigns ownership from other.

Parameters
otherHandle to move from; left null after the operation
Returns
Reference to this handle

Definition at line 568 of file ref_counted.hpp.

◆ operator=() [5/7]

template<typename Derived, typename Allocator>
template<typename Other>
requires std::convertible_to<Other*, Derived*>
RefCounted< Derived, Allocator > & helios::mem::RefCounted< Derived, Allocator >::operator= ( RefCounted< Other, Allocator > && other)
inlinenoexcept

Definition at line 605 of file ref_counted.hpp.

◆ operator=() [6/7]

template<typename Derived, typename Allocator>
template<typename Other>
requires std::convertible_to<Other*, Derived*>
RefCounted & helios::mem::RefCounted< Derived, Allocator >::operator= ( RefCounted< Other, Allocator > && other)
noexcept

Converting move-assignment from a compatible (derived) handle.

Template Parameters
OtherType convertible to Derived*
Parameters
otherHandle to move from; left null after the operation
Returns
Reference to this handle

◆ operator=() [7/7]

template<typename Derived, typename Allocator>
requires std::derived_from<Derived, RcFromThis<Derived>>
RefCounted< Derived, Allocator > & helios::mem::RefCounted< Derived, Allocator >::operator= ( std::nullptr_t )
inlinenoexcept

Assigns null, releasing any currently managed object.

Returns
Reference to this handle

Definition at line 619 of file ref_counted.hpp.

◆ operator==() [1/3]

template<typename Derived, typename Allocator>
bool helios::mem::RefCounted< Derived, Allocator >::operator== ( const RefCounted< Derived, Allocator > & other) const
inlinenodiscardnoexcept

Compares handle identity by managed pointer address.

Parameters
otherHandle to compare against
Returns
True when both handles refer to the same object

Definition at line 424 of file ref_counted.hpp.

◆ operator==() [2/3]

template<typename Derived, typename Allocator>
template<typename Other>
bool helios::mem::RefCounted< Derived, Allocator >::operator== ( const RefCounted< Other, Allocator > & other) const
inlinenodiscardnoexcept

Compares handle identity against a compatible derived handle.

Template Parameters
OtherDerived type convertible to Derived*
Parameters
otherHandle to compare against
Returns
True when both handles refer to the same object

Definition at line 443 of file ref_counted.hpp.

◆ operator==() [3/3]

template<typename Derived, typename Allocator>
bool helios::mem::RefCounted< Derived, Allocator >::operator== ( std::nullptr_t ) const
inlinenodiscardnoexcept

Checks whether the handle is null.

Returns
True when no object is managed

Definition at line 432 of file ref_counted.hpp.

◆ RefCount()

template<typename Derived, typename Allocator>
uint32_t helios::mem::RefCounted< Derived, Allocator >::RefCount ( ) const
inlinenodiscardnoexcept

Returns the current reference count.

Warning
Returns 0 if the handle is null.
Returns
Current reference count, or 0 for a null handle

Definition at line 471 of file ref_counted.hpp.

◆ Release()

template<typename Derived, typename Allocator>
requires std::derived_from<Derived, RcFromThis<Derived>>
Derived * helios::mem::RefCounted< Derived, Allocator >::Release ( )
inlinenodiscardnoexcept

Releases ownership without decrementing the ref count.

The caller becomes responsible for managing the object's lifetime.

Returns
Raw pointer that was managed, or nullptr

Definition at line 633 of file ref_counted.hpp.

◆ Reset()

template<typename Derived, typename Allocator>
requires std::derived_from<Derived, RcFromThis<Derived>>
void helios::mem::RefCounted< Derived, Allocator >::Reset ( )
inlinenoexcept

Releases ownership and resets the handle to null.

Decrements the ref count; destroys the object via the stored allocator if it reaches 0.

Definition at line 626 of file ref_counted.hpp.

◆ Unique()

template<typename Derived, typename Allocator>
bool helios::mem::RefCounted< Derived, Allocator >::Unique ( ) const
inlinenodiscardnoexcept

Checks if this handle is the sole owner of the managed object.

Returns
true if ref count == 1, false if null or ref count > 1

Definition at line 452 of file ref_counted.hpp.