TheAtlasEngine
 
Loading...
Searching...
No Matches
atlas::memory::strong_ptr< T > Class Template Reference

A non-nullable strong reference counted pointer. More...

#include <memory.hpp>

Public Types

using element_type = T
 

Public Member Functions

 strong_ptr ()=delete
 Delete default constructor - strong_ptr must always be valid.
 
 strong_ptr (std::nullptr_t)=delete
 Delete nullptr constructor - strong_ptr must always be valid.
 
 strong_ptr (strong_ptr const &p_other) noexcept
 Copy constructor.
 
template<typename U >
requires (std::is_convertible_v<U*, T*>)
 strong_ptr (strong_ptr< U > const &p_other) noexcept
 Converting copy constructor.
 
 strong_ptr (strong_ptr &&p_other) noexcept
 Move constructor that intentionally behaves like a copy constructor for safety.
 
strong_ptroperator= (strong_ptr &&p_other) noexcept
 Move assignment operator that behaves like a copy assignment for safety.
 
template<typename U >
 strong_ptr (strong_ptr< U > const &, void const *) noexcept
 Compile time error message for bad alias value.
 
template<typename U , detail::non_array_like M>
 strong_ptr (strong_ptr< U > const &p_other, M U::*p_member_ptr) noexcept
 Safe aliasing constructor for object members.
 
template<typename U , typename E , std::size_t N>
 strong_ptr (strong_ptr< U > const &p_other, std::array< E, N > U::*p_array_ptr, std::size_t p_index)
 Safe aliasing constructor for std::array members.
 
template<typename U , typename E , std::size_t N>
 strong_ptr (strong_ptr< U > const &p_other, E(U::*p_array_ptr)[N], std::size_t p_index)
 Safe aliasing constructor for C-array members.
 
 ~strong_ptr ()
 Destructor.
 
strong_ptroperator= (strong_ptr const &p_other) noexcept
 Copy assignment operator.
 
template<typename U >
requires (std::is_convertible_v<U*, T*>)
strong_ptroperator= (strong_ptr< U > const &p_other) noexcept
 Converting copy assignment operator.
 
void swap (strong_ptr &p_other) noexcept
 Swap the contents of this strong_ptr with another.
 
T & operator* () &&=delete
 Disable dereferencing for r-values (temporaries)
 
T * operator-> () &&=delete
 Disable member access for r-values (temporaries)
 
T & operator* () const &noexcept
 Dereference operator to access the managed object.
 
T * operator-> () const &noexcept
 Member access operator to access the managed object.
 
auto use_count () const noexcept
 Get the current reference count.
 

Friends

template<typename U >
class weak_ptr
 
template<typename U >
class optional_ptr
 
template<class U , typename... Args>
strong_ptr< U > make_strong_ptr (std::pmr::polymorphic_allocator<>, Args &&...)
 

Detailed Description

template<typename T>
class atlas::memory::strong_ptr< T >

A non-nullable strong reference counted pointer.

strong_ptr is a smart pointer that maintains shared ownership of an object through a reference count. It is similar to std::shared_ptr but with these key differences:

  1. Cannot be null - must always point to a valid object
  2. Can only be created via make_strong_ptr, not from raw pointers
  3. More memory efficient implementation

Use strong_ptr when you need shared ownership semantics and can guarantee the pointer will never be null. For nullable references, use optional_ptr.

Example usage:

++
// Create a strong_ptr to an object
auto ptr = hal::make_strong_ptr<my_i2c_driver>(allocator, arg1, arg2);
// Use the object using dereference (*) operator
(*ptr).configure({ .clock_rate = 250_kHz });
// OR use the object using arrow (->) operator
ptr->configure({ .clock_rate = 250_kHz });
// Share ownership with another driver or object
auto my_imu = hal::make_strong_ptr<my_driver>(allocator, ptr, 0x13);
Template Parameters
TThe type of the managed object

Constructor & Destructor Documentation

◆ strong_ptr() [1/7]

template<typename T >
atlas::memory::strong_ptr< T >::strong_ptr ( strong_ptr< T > const &  p_other)
inlinenoexcept

Copy constructor.

Creates a new strong reference to the same object.

Parameters
p_otherThe strong_ptr to copy from

◆ strong_ptr() [2/7]

template<typename T >
template<typename U >
requires (std::is_convertible_v<U*, T*>)
atlas::memory::strong_ptr< T >::strong_ptr ( strong_ptr< U > const &  p_other)
inlinenoexcept

Converting copy constructor.

Creates a new strong reference to the same object, converting from a derived type U to base type T.

Template Parameters
UA type convertible to T
Parameters
p_otherThe strong_ptr to copy from

◆ strong_ptr() [3/7]

template<typename T >
atlas::memory::strong_ptr< T >::strong_ptr ( strong_ptr< T > &&  p_other)
inlinenoexcept

Move constructor that intentionally behaves like a copy constructor for safety.

This move constructor deliberately performs a full copy operation rather than transferring ownership. This is a safety feature to prevent potential undefined behavior that could occur if code accidentally accessed a moved-from strong_ptr.

After this operation, both the source and destination objects remain in valid states, and the reference count is incremented by 1. This ensures that even if code incorrectly continues to use the source object after a move, no undefined behavior will occur.

Parameters
p_otherThe strong_ptr to "move" from (actually copied for safety)

◆ strong_ptr() [4/7]

template<typename T >
template<typename U >
atlas::memory::strong_ptr< T >::strong_ptr ( strong_ptr< U > const &  ,
void const *   
)
inlinenoexcept

Compile time error message for bad alias value.

std::shared_ptr provides an alias constructor that accepts any void* which is UB if that void* doesn't have the same lifetime as the object referenced by the std::shared_ptr. Users attempting to do this will get a list of constructors that failed to fit. This is not a good error message for users. Instead, we provide a static_assert message in plain english that explains why this overload fails at compile time.

Template Parameters
U- some type for the strong_ptr.

◆ strong_ptr() [5/7]

template<typename T >
template<typename U , detail::non_array_like M>
atlas::memory::strong_ptr< T >::strong_ptr ( strong_ptr< U > const &  p_other,
M U::*  p_member_ptr 
)
inlinenoexcept

Safe aliasing constructor for object members.

This constructor creates a strong_ptr that points to a member of an object managed by another strong_ptr. The resulting strong_ptr shares ownership with the original strong_ptr, keeping the entire parent object alive.

This version is only enabled for non-array members to prevent potential undefined behavior when accessing array elements directly. Use the array-specific versions instead.

Example usage:

struct container {
component part;
};
// Create a strong_ptr to the container
auto container_ptr = make_strong_ptr<container>(allocator);
// Create a strong_ptr to just the component
auto component_ptr = strong_ptr<component>(container_ptr,
&container::part);
Template Parameters
UType of the parent object
MType of the member
Parameters
p_otherThe strong_ptr to the parent object
p_member_ptrPointer-to-member identifying which member to reference

◆ strong_ptr() [6/7]

template<typename T >
template<typename U , typename E , std::size_t N>
atlas::memory::strong_ptr< T >::strong_ptr ( strong_ptr< U > const &  p_other,
std::array< E, N > U::*  p_array_ptr,
std::size_t  p_index 
)
inline

Safe aliasing constructor for std::array members.

This constructor creates a strong_ptr that points to an element of an array member in an object managed by another strong_ptr. It performs bounds checking to ensure the index is valid.

Example usage:

struct array_container {
std::array<element, 5> elements;
};
auto container_ptr = make_strong_ptr<array_container>(allocator);
// Get strong_ptr to the 2nd element
auto element_ptr = strong_ptr<element>(
container_ptr,
&array_container::elements,
2 // Index to access
);
Template Parameters
UType of the parent object
EType of the array element
NSize of the array
Parameters
p_otherThe strong_ptr to the parent object
p_array_ptrPointer-to-member identifying the array member
p_indexIndex of the element to reference
Exceptions
hal::out_of_rangeif index is out of bounds

◆ strong_ptr() [7/7]

template<typename T >
template<typename U , typename E , std::size_t N>
atlas::memory::strong_ptr< T >::strong_ptr ( strong_ptr< U > const &  p_other,
E(U::*)  p_array_ptr[N],
std::size_t  p_index 
)
inline

Safe aliasing constructor for C-array members.

This constructor creates a strong_ptr that points to an element of a C-style array member in an object managed by another strong_ptr. It performs bounds checking to ensure the index is valid.

Example usage:

struct c_array_container {
element elements[5];
};
auto container_ptr = make_strong_ptr<c_array_container>(allocator);
// Get strong_ptr to the 2nd element
auto element_ptr = strong_ptr<element>(
container_ptr,
&c_array_container::elements,
2 // Index to access
);
Template Parameters
UType of the parent object
EType of the array element
NSize of the array
Parameters
p_otherThe strong_ptr to the parent object
p_array_ptrPointer-to-member identifying the array member
p_indexIndex of the element to reference
Exceptions
hal::out_of_rangeif index is out of bounds

◆ ~strong_ptr()

template<typename T >
atlas::memory::strong_ptr< T >::~strong_ptr ( )
inline

Destructor.

Decrements the reference count and destroys the managed object if this was the last strong reference.

Member Function Documentation

◆ operator*()

template<typename T >
T & atlas::memory::strong_ptr< T >::operator* ( ) const &
inlinenoexcept

Dereference operator to access the managed object.

Returns
Reference to the managed object

◆ operator->()

template<typename T >
T * atlas::memory::strong_ptr< T >::operator-> ( ) const &
inlinenoexcept

Member access operator to access the managed object.

Returns
Pointer to the managed object

◆ operator=() [1/3]

template<typename T >
strong_ptr & atlas::memory::strong_ptr< T >::operator= ( strong_ptr< T > &&  p_other)
inlinenoexcept

Move assignment operator that behaves like a copy assignment for safety.

This move assignment operator deliberately performs a full copy operation rather than transferring ownership. This is a safety feature to prevent potential undefined behavior that could occur if code accidentally accessed a moved-from strong_ptr.

After this operation, both the source and destination objects remain in valid states, and the reference count is incremented by 1. This ensures that even if code incorrectly continues to use the source object after a move, no undefined behavior will occur.

Parameters
p_otherThe strong_ptr to "move" from (actually copied for safety)
Returns
Reference to *this

◆ operator=() [2/3]

template<typename T >
strong_ptr & atlas::memory::strong_ptr< T >::operator= ( strong_ptr< T > const &  p_other)
inlinenoexcept

Copy assignment operator.

Replaces the managed object with the one managed by p_other.

Parameters
p_otherThe strong_ptr to copy from
Returns
Reference to *this

◆ operator=() [3/3]

template<typename T >
template<typename U >
requires (std::is_convertible_v<U*, T*>)
strong_ptr & atlas::memory::strong_ptr< T >::operator= ( strong_ptr< U > const &  p_other)
inlinenoexcept

Converting copy assignment operator.

Replaces the managed object with the one managed by p_other, converting from type U to type T.

Template Parameters
UA type convertible to T
Parameters
p_otherThe strong_ptr to copy from
Returns
Reference to *this

◆ swap()

template<typename T >
void atlas::memory::strong_ptr< T >::swap ( strong_ptr< T > &  p_other)
inlinenoexcept

Swap the contents of this strong_ptr with another.

Parameters
p_otherThe strong_ptr to swap with

◆ use_count()

template<typename T >
auto atlas::memory::strong_ptr< T >::use_count ( ) const
inlinenoexcept

Get the current reference count.

This is primarily for testing purposes.

Returns
The number of strong references to the managed object

The documentation for this class was generated from the following file: