Bifrost SDK
Bifrost SDK documentation
Amino::Ptr< T > Class Template Reference

Smart pointers allowing custom user classes (opaque classes) to be used within Amino graphs. More...

#include <Ptr.h>

Inheritance diagram for Amino::Ptr< T >:
Amino::MutablePtr< T >

Public Types

using element_type = T
 The type of objects referenced by the Ptr pointer. More...
 
using element_const_reference_type = typename std::add_lvalue_reference< const element_type >::type
 A reference to a const element_type. More...
 
using use_count_type = std::intptr_t
 The integral type of the use count. More...
 

Public Member Functions

 Ptr (PtrDefaultFlag)
 Construct a Ptr with a default value pointee. More...
 
template<class Y , class >
Ptr< T > & operator= (Ptr< Y > const &rhs) noexcept
 
template<class Y , class >
Ptr< T > & operator= (Ptr< Y > &&rhs) noexcept
 
template<class Y , class >
Ptr< T > & operator= (MutablePtr< Y > rhs) noexcept
 
Empty constructors
constexpr Ptr () noexcept
 Construct an empty pointer. More...
 
constexpr Ptr (std::nullptr_t) noexcept
 Construct an empty pointer. More...
 
Constructors
template<class Y , class = if_compliant_and_convertible_from<Y>>
 Ptr (Y *p)
 Construct a pointer that owns the object pointed by p. More...
 
template<class Y , class D , class = if_compliant_and_convertible_from<Y>>
 Ptr (Y *p, D d)
 Construct a pointer that owns the object pointed by p. More...
 
Templated null constructors
template<class D >
 Ptr (std::nullptr_t, D d)
 Construct a pointer to a null object with a specific deleter. More...
 
Copy constructors
 Ptr (Ptr const &rhs) noexcept
 Copy constructor. More...
 
template<class Y , class = if_convertible_from<Y>>
 Ptr (Ptr< Y > const &rhs) noexcept
 Conversion constructor. More...
 
Move constructors
 Ptr (Ptr &&rhs) noexcept
 Move constructor. More...
 
template<class Y , class = if_convertible_from<Y>>
 Ptr (Ptr< Y > &&rhs) noexcept
 Move conversion. More...
 
template<class Y , class = if_convertible_from<Y>>
 Ptr (MutablePtr< Y > rhs) noexcept
 Conversion constructor from a MutablePtr. More...
 
Destructor
 ~Ptr ()
 Destructor. More...
 
Assignment operators
Ptroperator= (Ptr const &rhs) noexcept
 Assignment operator. More...
 
template<class Y , class = if_convertible_from<Y>>
Ptroperator= (Ptr< Y > const &rhs) noexcept
 Assignment conversion. More...
 
Move assignment operators
Ptroperator= (Ptr &&rhs) noexcept
 Move assignment operator. More...
 
template<class Y , class = if_convertible_from<Y>>
Ptroperator= (Ptr< Y > &&rhs) noexcept
 Move assignment conversion. More...
 
template<class Y , class = if_convertible_from<Y>>
Ptroperator= (MutablePtr< Y > rhs) noexcept
 Move assignment conversion from a MutablePtr. More...
 
Modifiers
void swap (Ptr &rhs) noexcept
 Swap two pointers. More...
 
void reset () noexcept
 Reset the pointer to an empty pointer. More...
 
template<class Y , class = if_compliant_and_convertible_from<Y>>
void reset (Y *p)
 Reset the content of the Ptr to now manage the given pointer. More...
 
template<class Y , class D , class = if_compliant_and_convertible_from<Y>>
void reset (Y *p, D d)
 Reset the content of the Ptr to now manage the given pointer. More...
 
MutablePtr< element_typetoMutable () noexcept
 Conversion to MutablePtr. More...
 
Special modifier

Short-hand to allow modifying the pointee held by this Ptr when its ownership is known to be unique (use_count() == 1).

This can be useful in some scenario, but in general it is recommended to use a guard (see Amino::PtrGuard and Amino::createPtrGuard) to mutate the pointee.

Parameters
funcA functor that takes a non-const pointee.
Precondition
unique() == true
Postcondition
unique() == true
Amino::Ptr<T> ptr = createMyPtr();
// We know it's unique because it was just created.
assert(ptr.unique());
// Therefore it's safe to mutate.
ptr.mutate([](T* ptee) {
ptee.modify();
});
Smart pointers allowing custom user classes (opaque classes) to be used within Amino graphs.
Definition: Ptr.h:207
void mutate(Func &&func)
Definition: Ptr.h:1247
bool unique() const noexcept
Returns whether the object is uniquely owned by the pointer.
Definition: Ptr.h:1297
template<typename Func >
void mutate (Func &&func)
 
Accessors
element_const_reference_type operator* () const noexcept
 Indirection. More...
 
element_type const * operator-> () const noexcept
 Indirection. More...
 
element_type const * get () const noexcept
 Accessor. More...
 
bool unique () const noexcept
 Returns whether the object is uniquely owned by the pointer. More...
 
use_count_type use_count () const noexcept
 Returns the use count of the pointed object. More...
 
 operator bool () const noexcept
 Returns whether the pointer is non-null. More...
 
template<class Y >
bool owner_before (Ptr< Y > const &rhs) const noexcept
 Owner-based ordering of Ptr. More...
 

Friends

template<class Y >
class Ptr
 Friendship to allow conversion between pointers of different types. More...
 
template<class Y >
class PtrGuard
 Friendship to allow access to getPointee, getCtrlBlck, and init. Used when the guard is created with the Amino::PtrGuardUniqueFlag. More...
 

Detailed Description

template<class T>
class Amino::Ptr< T >

Smart pointers allowing custom user classes (opaque classes) to be used within Amino graphs.

Warning
Amino::Ptr is NOT replacements for standard smart pointers (like std::shared_ptr). It is only meant to be used within Amino graphs. Therefore, if a value never needs to flow directly into the graph, a standard smart pointer (like std::shared_ptr) should be used instead.

This class is a smart pointer used to manage the life-scope of the pointee objects and help implementing persistent data structures, respecting value semantics.

In general, in Amino, a Ptr pointer would be referring to objects of following types:

The Ptr class stores a pointer to a dynamically allocated object. The object is typically allocated using the C++ new operator. An optional customizable deleter can be specified in case the object hasn't been allocated with the C++ new operator.

Ptr references are implemented using reference counting, and the pointed object is automatically released when no remaining Ptr is referencing it.

Because the pointee of a Ptr is always const, and the compiler checks for constness, there is no possibility of cyclic references between objects.

Copying a Ptr creates a new reference to the same object. This operation is thread-safe. Ptr can thus be safely passed to other threads.

Accesses to the pointed object are not synchronized between threads. Other means of protection must be used to insure the thread-safety of the pointed object. This is unnecessary for immutable objects as these are trivially thread-safe.

The pointed object of Ptr is always const. This allows embedding of Ptr in other const objects (structs, lists, arrays), giving a immutable overall data structure as a result.

Warning
In that respect, Amino::Ptr is different than std::shared_ptr. Amino::Ptr since access to the pointee is always const, unlike std::shared_ptr. This allows Amino::Ptr to be safely used to implement Persistent Data Structures. See Amino::Ptr::toMutable() for details.

The Ptr class meets the CopyConstructible, MoveConstructible, CopyAssignable and MoveAssignable requirements of the C++ Standard Library. Thus, Ptr objects can be stored in standard library containers. Comparison operators and a hash functor are supplied so that Ptr works with the standard library's associative containers.

Precondition
The dynamically allocated pointee class T must satisfy some criterion to be allowed to be stored in a Ptr. In particular, it must be copy constructible, because this is required to allocate a copy, when calling Amino::Ptr::toMutable(). The complete list of requirements on the pointee type T can be found in Amino::PointeeTraits.
Warning
The type T may not be the actual type of the dynamically allocated object, since the Ptr could have been downcasted (Ptr<BaseClass>) or type erased (Ptr<void>).
Note
If a function returns an Amino::Ptr then it is up to calling code to keep it alive while the calling code accesses the pointee.
Warning
It is recommended to avoid type-erasure (Ptr<void>) as much a possible. Static casting Ptr from/to void to type can lead to very subtle bugs, since potential "casters" must "agree" on the exact type T to use when casting to void or casting to T. Otherwise, this could lead to pointer misalignments (for example for classes with multiple inheritance), which would in turn lead to undefined behavior.
Template Parameters
TThe type of objects referenced by the Ptr pointer.

Definition at line 207 of file Ptr.h.

Member Typedef Documentation

◆ element_const_reference_type

template<class T >
using Amino::Ptr< T >::element_const_reference_type = typename std::add_lvalue_reference<const element_type>::type

A reference to a const element_type.

Definition at line 244 of file Ptr.h.

◆ element_type

template<class T >
using Amino::Ptr< T >::element_type = T

The type of objects referenced by the Ptr pointer.

Definition at line 241 of file Ptr.h.

◆ use_count_type

template<class T >
using Amino::Ptr< T >::use_count_type = std::intptr_t

The integral type of the use count.

Definition at line 248 of file Ptr.h.

Constructor & Destructor Documentation

◆ Ptr() [1/11]

template<class T >
constexpr Amino::Ptr< T >::Ptr
inlineconstexprnoexcept

Construct an empty pointer.

Postcondition
get() == nullptr
use_count() == 0

Definition at line 1042 of file Ptr.h.

◆ Ptr() [2/11]

template<class T >
constexpr Amino::Ptr< T >::Ptr ( std::nullptr_t  )
inlineconstexprnoexcept

Construct an empty pointer.

Postcondition
get() == nullptr
use_count() == 0

Definition at line 1047 of file Ptr.h.

◆ Ptr() [3/11]

template<class T >
Amino::Ptr< T >::Ptr ( PtrDefaultFlag  )
inlineexplicit

Construct a Ptr with a default value pointee.

See also
PtrDefaultFlag

Definition at line 1897 of file Ptr.h.

◆ Ptr() [4/11]

template<class T >
template<class Y , class >
Amino::Ptr< T >::Ptr ( Y *  p)
inlineexplicit

Construct a pointer that owns the object pointed by p.

The object will be deleted using the expression Amino::PointeeManager::checkedDelete(p). As such, must be of a complete type. The pointer p used for deletion is captured at construction time of the Ptr.

The constructor is only considered if a Y* can be implicitly converted to a T*.

Postcondition
get() == p
use_count() == 1
Parameters
[in]pa pointer to an object allocated via a C++ new expression or a null pointer.

Definition at line 1053 of file Ptr.h.

◆ Ptr() [5/11]

template<class T >
template<class Y , class D , class >
Amino::Ptr< T >::Ptr ( Y *  p,
d 
)
inline

Construct a pointer that owns the object pointed by p.

The pointer deleter is set to d. The object will be destructed using the expression d(p). The deleter is invoked in all cases even when the pointer is null. The pointer p used for deletion is captured at construction time of the Ptr.

The constructor is only considered if a Y* can be implicitly converted to a T*.

Postcondition
get() == p
use_count() == 1
Parameters
[in]pa pointer to an object to be owned by the pointer or a null pointer.
[in]dthe deleter to invoke when the object is not longer referenced by any Ptr.

Definition at line 1067 of file Ptr.h.

◆ Ptr() [6/11]

template<class T >
template<class D >
Amino::Ptr< T >::Ptr ( std::nullptr_t  ,
d 
)
inline

Construct a pointer to a null object with a specific deleter.

The pointer deleter is set to d. The null object will be destructed using the expression d(nullptr) when it is no longer referenced.

Postcondition
get() == nullptr
use_count() == 1
Parameters
[in]dthe deleter to invoke when the object is not longer referenced by any Ptr.

Definition at line 1079 of file Ptr.h.

◆ Ptr() [7/11]

template<class T >
Amino::Ptr< T >::Ptr ( Ptr< T > const &  rhs)
inlinenoexcept

Copy constructor.

If rhs is empty, constructs an empty Ptr; otherwise, constructs a Ptr that shares ownership with rhs.

Postcondition
get() == rhs.get()
use_count() == rhs.use_count()
Parameters
[in]rhsthe pointer to be copied

Definition at line 1098 of file Ptr.h.

◆ Ptr() [8/11]

template<class T >
template<class Y , class >
Amino::Ptr< T >::Ptr ( Ptr< Y > const &  rhs)
inlinenoexcept

Conversion constructor.

If rhs is empty, constructs an empty Ptr; otherwise, constructs a Ptr that shares ownership with rhs. T

The conversion constructor is only considered if a Y* can be implicitly converted to a T*.

Postcondition
get() == rhs.get()
use_count() == rhs.use_count()
Parameters
[in]rhsthe pointer to be copied

Definition at line 1107 of file Ptr.h.

◆ Ptr() [9/11]

template<class T >
Amino::Ptr< T >::Ptr ( Ptr< T > &&  rhs)
inlinenoexcept

Move constructor.

Postcondition
*this contains the old value of rhs
rhs is empty
Parameters
[in]rhsthe pointer to be moved

Definition at line 1115 of file Ptr.h.

◆ Ptr() [10/11]

template<class T >
template<class Y , class >
Amino::Ptr< T >::Ptr ( Ptr< Y > &&  rhs)
inlinenoexcept

Move conversion.

The conversion constructor is only considered if a Y* can be implicitly converted to a T*.

Postcondition
*this contains the old value of rhs
rhs is empty
Parameters
[in]rhsthe pointer to be moved

Definition at line 1124 of file Ptr.h.

◆ Ptr() [11/11]

template<class T >
template<class Y , class >
Amino::Ptr< T >::Ptr ( MutablePtr< Y >  rhs)
inlinenoexcept

Conversion constructor from a MutablePtr.

The conversion constructor is only considered if a Y* can be implicitly converted to a T*.

Postcondition
use_count() == 1 if rhs was not empty use_count() == 0 otherwise.`
Parameters
[in]rhsthe MutablePtr to steal the pointee from.

Definition at line 1133 of file Ptr.h.

◆ ~Ptr()

template<class T >
Amino::Ptr< T >::~Ptr ( )
inlinedefault

Destructor.

If the pointer is empty, nothing occurs.

If the pointer owns an object, the use_count of the pointers sharing ownership with the current pointer is decremented by one. If the use_count reaches zero, the expression Amino::PointeeManager::checkedDelete(p) or d(p) is invoked; where d is an optional deleter and p is the pointer specified when the first Ptr was constructed (i.e. the current value of the pointer is not used).

Member Function Documentation

◆ get()

template<class T >
Ptr< T >::element_type const * Amino::Ptr< T >::get
inlinenoexcept

Accessor.

Returns
the pointer to the pointed object

Definition at line 1282 of file Ptr.h.

Referenced by Amino::MutablePtr< T >::operator*(), and Amino::MutablePtr< T >::operator->().

◆ mutate()

template<class T >
template<typename Func >
void Amino::Ptr< T >::mutate ( Func &&  func)

Definition at line 1247 of file Ptr.h.

References Amino::Ptr< T >::unique().

◆ operator bool()

template<class T >
Amino::Ptr< T >::operator bool
inlineexplicitnoexcept

Returns whether the pointer is non-null.

Returns
get() != nullptr

Definition at line 1304 of file Ptr.h.

◆ operator*()

template<class T >
Ptr< T >::element_const_reference_type Amino::Ptr< T >::operator*
inlinenoexcept

Indirection.

Precondition
the pointer must not be null or empty
Returns
the reference to the pointed object

Definition at line 1264 of file Ptr.h.

◆ operator->()

template<class T >
Ptr< T >::element_type const * Amino::Ptr< T >::operator->
inlinenoexcept

Indirection.

Precondition
the pointer must not be null
Returns
the pointer to the pointed object

Definition at line 1273 of file Ptr.h.

◆ operator=() [1/8]

template<class T >
template<class Y , class = if_convertible_from<Y>>
Ptr & Amino::Ptr< T >::operator= ( MutablePtr< Y >  rhs)
noexcept

Move assignment conversion from a MutablePtr.

The assignment conversion is only considered if a Y* can be implicitly converted to a T*.

Postcondition
use_count() == 1 if rhs was not empty use_count() == 0 otherwise.`
Parameters
[in]rhsthe MutablePtr to steal the pointee from.
Returns
*this

◆ operator=() [2/8]

template<class T >
template<class Y , class >
Ptr< T > & Amino::Ptr< T >::operator= ( MutablePtr< Y >  rhs)
inlinenoexcept

Definition at line 1182 of file Ptr.h.

◆ operator=() [3/8]

template<class T >
Ptr< T > & Amino::Ptr< T >::operator= ( Ptr< T > &&  rhs)
inlinenoexcept

Move assignment operator.

Move assign the pointer rhs to *this.

Postcondition
*this contains the old value of rhs
rhs is empty
Parameters
[in]rhsthe source of the assignment
Returns
*this

Definition at line 1164 of file Ptr.h.

◆ operator=() [4/8]

template<class T >
Ptr< T > & Amino::Ptr< T >::operator= ( Ptr< T > const &  rhs)
inlinenoexcept

Assignment operator.

Assign the pointer rhs to *this. Both pointers will point to the same object.

Postcondition
get() == rhs.get()
use_count() == rhs.use_count()
Parameters
[in]rhsthe source of the assignment
Returns
*this

Definition at line 1147 of file Ptr.h.

◆ operator=() [5/8]

template<class T >
template<class Y , class = if_convertible_from<Y>>
Ptr & Amino::Ptr< T >::operator= ( Ptr< Y > &&  rhs)
noexcept

Move assignment conversion.

Assign the pointer rhs to *this.

The assignment conversion is only considered if a Y* can be implicitly converted to a T*.

Postcondition
*this contains the old value of rhs
rhs is empty
Parameters
[in]rhsthe source of the assignment
Returns
*this

◆ operator=() [6/8]

template<class T >
template<class Y , class >
Ptr< T > & Amino::Ptr< T >::operator= ( Ptr< Y > &&  rhs)
inlinenoexcept

Definition at line 1173 of file Ptr.h.

References Amino::Ptr().

◆ operator=() [7/8]

template<class T >
template<class Y , class = if_convertible_from<Y>>
Ptr & Amino::Ptr< T >::operator= ( Ptr< Y > const &  rhs)
noexcept

Assignment conversion.

Assign the pointer rhs to *this. Both pointers will point to the same object, therefore increasing the use count by one.

The assignment conversion is only considered if a Y* can be implicitly converted to a T*.

Parameters
[in]rhsthe source of the assignment
Returns
*this

◆ operator=() [8/8]

template<class T >
template<class Y , class >
Ptr< T > & Amino::Ptr< T >::operator= ( Ptr< Y > const &  rhs)
inlinenoexcept

Definition at line 1156 of file Ptr.h.

References Amino::Ptr().

◆ owner_before()

template<class T >
template<class Y >
bool Amino::Ptr< T >::owner_before ( Ptr< Y > const &  rhs) const
inlinenoexcept

Owner-based ordering of Ptr.

Compare two pointers and return whether one comes before the other one in some unspecified owner-based strict weak ordering. The order is such that two smart pointers compare equivalent only if they are both empty or if they share ownership, even if the values of the pointers obtained by get() are different (e.g. because they point at different sub-objects within the same object).

Returns
true if *this comes before rhs in a the owner-based ordering; false otherwise.

Definition at line 1312 of file Ptr.h.

◆ reset() [1/3]

template<class T >
void Amino::Ptr< T >::reset
inlinenoexcept

Reset the pointer to an empty pointer.

This is equivalent to *this = Ptr().

Postcondition
get() == nullptr
use_count() == 0

Definition at line 1197 of file Ptr.h.

References Amino::Ptr().

◆ reset() [2/3]

template<class T >
template<class Y , class >
void Amino::Ptr< T >::reset ( Y *  p)
inline

Reset the content of the Ptr to now manage the given pointer.

This is equivalent to *this = Ptr(p).

The member function is only considered if a Y* can be implicitly converted to a T*.

Postcondition
get() == p
use_count() == 1
Parameters
[in]pa pointer to an object to be owned by the pointer or a null pointer.

Definition at line 1205 of file Ptr.h.

References Amino::Ptr().

◆ reset() [3/3]

template<class T >
template<class Y , class D , class >
void Amino::Ptr< T >::reset ( Y *  p,
d 
)
inline

Reset the content of the Ptr to now manage the given pointer.

This is equivalent to *this = Ptr(p,d).

The member function is only considered if a Y* can be implicitly converted to a T*.

Postcondition
get() == p
use_count() == 1
Parameters
[in]pa pointer to an object to be owned by the pointer or a null pointer.
[in]dthe deleter to invoke when the object is not longer referenced by any Ptr.

Definition at line 1213 of file Ptr.h.

References Amino::Ptr().

◆ swap()

template<class T >
void Amino::Ptr< T >::swap ( Ptr< T > &  rhs)
inlinenoexcept

Swap two pointers.

Exchanges the contents of the two Ptr.

Parameters
[in]rhsthe pointer to swap with

Definition at line 1190 of file Ptr.h.

References Amino::swap().

Referenced by Amino::MutablePtr< T >::toImmutable().

◆ toMutable()

template<class T >
MutablePtr< typename Ptr< T >::element_type > Amino::Ptr< T >::toMutable
inlinenoexcept

Conversion to MutablePtr.

This member function allows one to convert a Ptr<X> to a MutablePtr<X>. The referenced object is cloned if necessary.

This member function returns an empty MutablePtr if the *this pointer is empty.

If the pointee object is not uniquely owned, a copy of the object is made and a MutablePtr to the mutable copied object is returned. The copy constructor of the dynamically allocated object that was captured upon creating the Ptr managing that object is used to make a copy of the object.

If the pointee object is uniquely owned, the ownership of the pointee is simply transferred to the returned MutablePtr and the pointee object will not be copied.

Regardless if the pointee is uniquely owned or not, the *this pointer will be reset after the call to toMutable().

Postcondition
get() == nullptr
use_count() == 0
Returns
a MutablePtr to the uniquely owned object.

Definition at line 1220 of file Ptr.h.

◆ unique()

template<class T >
bool Amino::Ptr< T >::unique
inlinenoexcept

Returns whether the object is uniquely owned by the pointer.

Returns
use_count() == 1

Definition at line 1297 of file Ptr.h.

Referenced by Amino::Ptr< T >::mutate().

◆ use_count()

template<class T >
Ptr< T >::use_count_type Amino::Ptr< T >::use_count
inlinenoexcept

Returns the use count of the pointed object.

Warning
Use only for debugging and testing purposes, not for production code. Consider using unique() instead.

In a multi-threaded environment, use_count() will return you an instantaneous snapshot of its value. It's value might have already changed as soon as the function returns. The only reliable return value is the value "1" which implies that the only remaining reference is own the current thread (assuming that the Ptr object itself is local to the current thread).

Returns
the number of Ptr referencing the pointed object

Definition at line 1289 of file Ptr.h.

Friends And Related Function Documentation

◆ Ptr

template<class T >
template<class Y >
friend class Ptr
friend

Friendship to allow conversion between pointers of different types.

Definition at line 686 of file Ptr.h.

◆ PtrGuard

template<class T >
template<class Y >
friend class PtrGuard
friend

Friendship to allow access to getPointee, getCtrlBlck, and init. Used when the guard is created with the Amino::PtrGuardUniqueFlag.

Definition at line 691 of file Ptr.h.