CsPointer  1.0.1
CsPointer::CsIntrusivePointer< T, Policy > Class Template Reference

Manages a pointer to an object, the reference count is stored in the object. More...

Public Typedefs

using pointer = T *
 
using element_type = T
 
using Pointer = pointer
 
using ElementType = element_type
 

Public Member Functions

constexpr CsIntrusivePointer () noexcept
 
constexpr CsIntrusivePointer (std::nullptr_t) noexcept
 
template<typename U >
 CsIntrusivePointer (U *p)
 
 ~CsIntrusivePointer ()
 
 CsIntrusivePointer (const CsIntrusivePointer &other)
 
CsIntrusivePointer & operator= (const CsIntrusivePointer &other)
 
 CsIntrusivePointer (CsIntrusivePointer &&other) noexcept
 
CsIntrusivePointer & operator= (CsIntrusivePointer &&other) noexcept
 
CsIntrusivePointer & operator= (T *p)
 
template<typename U >
 CsIntrusivePointer (const CsIntrusivePointer< U > &p) noexcept
 
template<typename U >
CsIntrusivePointer & operator= (const CsIntrusivePointer< U > &p)
 
template<typename U >
 CsIntrusivePointer (CsIntrusivePointer< U > &&p) noexcept
 
template<typename U >
CsIntrusivePointer & operator= (CsIntrusivePointer< U > &&p)
 
T & operator* () const noexcept
 
T * operator-> () const noexcept
 
bool operator! () const noexcept
 
 operator bool () const
 
void clear () noexcept
 
Pointer data () const noexcept
 
Pointer get () const noexcept
 
bool is_null () const noexcept
 
Pointer release_if () noexcept
 
void reset ()
 
template<typename U >
void reset (U *p)
 
void swap (CsIntrusivePointer &other) noexcept
 
std::size_t use_count () const noexcept
 

Related Functions

These are not member functions

CsIntrusivePointer< T > make_intrusive (Args &&...args)
 
CsIntrusivePointer< T > const_pointer_cast (const CsIntrusivePointer< U > &ptr)
 
CsIntrusivePointer< T > dynamic_pointer_cast (const CsIntrusivePointer< U > &ptr)
 
CsIntrusivePointer< T > static_pointer_cast (const CsIntrusivePointer< U > &ptr)
 
CsIntrusivePointer< T > const_pointer_cast (CsIntrusivePointer< U > &&ptr)
 
CsIntrusivePointer< T > dynamic_pointer_cast (CsIntrusivePointer< U > &&ptr)
 
CsIntrusivePointer< T > static_pointer_cast (CsIntrusivePointer< U > &&ptr)
 
bool operator== (const CsIntrusivePointer< T1 > &ptr1, const CsIntrusivePointer< T2 > &ptr2) noexcept
 
bool operator== (const CsIntrusivePointer< T1 > &ptr1, const T2 *ptr2) noexcept
 
bool operator== (const T1 *ptr1, const CsIntrusivePointer< T2 > &ptr2) noexcept
 
bool operator== (const CsIntrusivePointer< T > &ptr1, std::nullptr_t) noexcept
 
bool operator== (std::nullptr_t, const CsIntrusivePointer< T > &ptr2) noexcept
 
bool operator!= (const CsIntrusivePointer< T1 > &ptr1, const CsIntrusivePointer< T2 > &ptr2) noexcept
 
bool operator!= (const CsIntrusivePointer< T1 > &ptr1, const T2 *ptr2) noexcept
 
bool operator!= (const T1 *ptr1, const CsIntrusivePointer< T2 > &ptr2) noexcept
 
bool operator!= (const CsIntrusivePointer< T > &ptr1, std::nullptr_t) noexcept
 
bool operator!= (std::nullptr_t, const CsIntrusivePointer< T > &ptr2) noexcept
 
bool operator< (const CsIntrusivePointer< T1 > &ptr1, const CsIntrusivePointer< T2 > ptr2)
 
bool operator<= (const CsIntrusivePointer< T1 > &ptr1, const CsIntrusivePointer< T2 > ptr2)
 
bool operator> (const CsIntrusivePointer< T1 > &ptr1, const CsIntrusivePointer< T2 > ptr2)
 
bool operator>= (const CsIntrusivePointer< T1 > &ptr1, const CsIntrusivePointer< T2 > ptr2)
 
void swap (CsIntrusivePointer< T > &ptr1, CsIntrusivePointer< T > &ptr2) noexcept
 
enum CsIntrusiveAction
 

Detailed Description

template<typename T, typename Policy = CsIntrusiveDefaultPolicy>
class CsPointer::CsIntrusivePointer< T, Policy >

The CsIntrusivePointer class manages a pointer to an object, the reference count is stored in the object. The reference count is incremented each time a new intrusive pointer is created, copied, or assigned to point to the given object. When an existing intrusive pointer is destroyed, assigned a new value, or the value is cleared, the reference count will be decremented. When the reference count becomes zero the given object will be deleted.

This is a templated class with parameters T and Policy. The argument passed for T defines the data type of the object, this pointer will point to. The argument for Policy is defaulted to CsIntrusiveDefaultPolicy. You can pass a custom policy class if your application needs to redefine the implementation for incrementing or decrementing the reference count.

The following are a few advantages for using an intrusive pointer rather than a shared pointer.

  • Intrusive pointer does not require any extra memory allocation to store the reference count
  • If an existing intrusive pointer points to an object and a new intrusive pointer is constructed using a raw pointer to that same object, both intrusive pointers share the reference count
  • This class can be used with any existing class which already supports a reference count stored in the T object

How to Use this Class

There are two different approaches for how to use the CsIntrusivePointer class. The most common use case is to modify some base class in your application. You must inherit from CsIntrusiveBase, not from CsIntrusivePointer. Using the code shown below, the reference count will be stored in the BaseObject class.

class BaseObject : public CsPointer::CsIntrusiveBase

There is another way to use CsIntrusivePointer when an existing base class already stores and maintains a reference count. A common place this occurs is with Windows COM objects. The COM base class IUnknown provides the methods AddRef() and Release() to increment and decrement the reference count. With this approach you must implement a custom CsIntrusiveDefaultPolicy class and call the two IUnknown methods.

class BaseObject : public IUnknown

Methods

The simplest way to create a new intrusive pointer is to call the free function make_intrusive() as shown below.

CsPointer::CsIntrusivePointer<Widget> ip_ptr = CsPointer::make_intrusive<Widget>();
See also
CsIntrusiveBase, CsIntrusiveDefaultPolicy

Member Typedef Documentation

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsIntrusivePointer::element_type

Typedef for T.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsIntrusivePointer::ElementType

Typedef for element_type.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsIntrusivePointer::pointer

Typedef for element_type *.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsIntrusivePointer::Pointer

Typedef for pointer.

Constructor & Destructor Documentation

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
constexpr CsIntrusivePointer::CsIntrusivePointer ( )
inlineconstexprnoexcept

Creates a new CsIntrusivePointer which contains a nullptr.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
constexpr CsIntrusivePointer::CsIntrusivePointer ( std::nullptr_t  )
inlineconstexprnoexcept

Creates a new CsIntrusivePointer which contains a nullptr.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
template<typename U >
CsIntrusivePointer::CsIntrusivePointer ( U *  p)
inlineexplicit

Creates a new CsIntrusivePointer which points to p. Ownership of the object is transferred to the new intrusive pointer.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsIntrusivePointer::~CsIntrusivePointer ( )
inline

Destroys this CsIntrusivePointer. If the current intrusive pointer is not a nullptr, then the reference count in the object it currently points to is decremented. If the reference count is now zero, the object being pointed to will be destroyed.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsIntrusivePointer::CsIntrusivePointer ( const CsIntrusivePointer< T, Policy > &  other)
inline

Copy constructs a new CsIntrusivePointer from other. The current intrusive pointer shares ownership with other.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsIntrusivePointer::CsIntrusivePointer ( CsIntrusivePointer< T, Policy > &&  other)
inlinenoexcept

Move constructs a new CsIntrusivePointer from other. The value of other will be set to a nullptr.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
template<typename U >
CsIntrusivePointer::CsIntrusivePointer ( const CsIntrusivePointer< U > &  p)
inlinenoexcept

Constructs a new CsIntrusivePointer from p. This intrusive pointer shares ownership with other. The template parameter U must inherit from T.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
template<typename U >
CsIntrusivePointer::CsIntrusivePointer ( CsIntrusivePointer< U > &&  p)
inlinenoexcept

Constructs a CsIntrusivePointer by moving the ownership from p. The template parameter U must inherit from T.

Member Function Documentation

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
void CsIntrusivePointer::clear ( )
inlinenoexcept

Sets the current CsIntrusivePointer to a nullptr. If the current intrusive pointer is not a nullptr, then the reference count in the object it currently points to is decremented. If the reference count is now zero, the object being pointed to will be destroyed.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
Pointer CsIntrusivePointer::data ( ) const
inlinenoexcept

Returns the value of the pointer contained in this object.

Note
Do not delete the object pointed to by the raw pointer returned by this method. This will cause undefined behavior.
template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
Pointer CsIntrusivePointer::get ( ) const
inlinenoexcept

Equivalent to calling data().

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
bool CsIntrusivePointer::is_null ( ) const
inlinenoexcept

Returns true if the current CsIntrusivePointer contains a nullptr.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsIntrusivePointer::operator bool ( ) const
inline

Returns true if the current CsIntrusivePointer is not a nullptr. This method is called when a intrusive pointer is used in an "if statement" or another context where a boolean value is expected. Since this method is explicit it is not possible to assign a intrusive pointer to a boolean.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
bool CsIntrusivePointer::operator! ( ) const
inlinenoexcept

Returns true if this object is a nullptr. This method is called when a intrusive pointer is used in an "if statement" or another context where a boolean value is expected.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
T & CsIntrusivePointer::operator* ( ) const
inlinenoexcept

Returns a reference to the object the current CsIntrusivePointer is pointing to.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
T * CsIntrusivePointer::operator-> ( ) const
inlinenoexcept

Returns a pointer to the object the current CsIntrusivePointer is pointing to.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsIntrusivePointer & CsIntrusivePointer::operator= ( const CsIntrusivePointer< T, Policy > &  other)
inline

Copy assigns from other and returns a reference to this object. If the current intrusive pointer is not a nullptr, then the reference count in the object it currently points to is decremented. If the reference count is now zero, the object being pointed to will be destroyed.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
template<typename U >
CsIntrusivePointer & CsIntrusivePointer::operator= ( const CsIntrusivePointer< U > &  p)
inline

Assigns from p and returns a reference to this object. The template parameter U must inherit from T.

If the current intrusive pointer is not a nullptr, then the reference count in the object it currently points to is decremented. If the reference count is now zero, the object being pointed to will be destroyed.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsIntrusivePointer & CsIntrusivePointer::operator= ( CsIntrusivePointer< T, Policy > &&  other)
inlinenoexcept

Move assigns from other and returns a reference to this object. The value of other will be set to a nullptr.

If the current intrusive pointer is not a nullptr, then the reference count in the object it currently points to is decremented. If the reference count is now zero, the object being pointed to will be destroyed.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
template<typename U >
CsIntrusivePointer & CsIntrusivePointer::operator= ( CsIntrusivePointer< U > &&  p)
inline

Assigns by moving the ownership from p and returns a reference to this object. The template parameter U must inherit from T.

If the current intrusive pointer is not a nullptr, then the reference count in the object it currently points to is decremented. If the reference count is now zero, the object being pointed to will be destroyed.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsIntrusivePointer & CsIntrusivePointer::operator= ( T *  p)
inline

Assigns p to the current CsIntrusivePointer. Ownership of the object pointed to by p is transferred to the current intrusive pointer.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
Pointer CsIntrusivePointer::release_if ( )
inlinenoexcept

Releases the ownership of the managed object, if this intrusive pointer is not a nullptr and the reference count is equal to 1. The process involves decrementing the reference count without deleting the object and then setting the current intrusive pointer to a nullptr. The old value of the internal raw pointer is returned. The caller is responsible for deleting the object.

If the reference count was greater than 1 this method does nothing and returns a nullptr.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
void CsIntrusivePointer::reset ( )
inline

Equivalent to calling clear().

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
template<typename U >
void CsIntrusivePointer::reset ( U *  p)
inline

Resets the current CsIntrusivePointer object to point to p. The template parameter U must inherit from T.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
void CsIntrusivePointer::swap ( CsIntrusivePointer< T, Policy > &  other)
inlinenoexcept

Swaps the current CsIntrusivePointer with other.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
std::size_t CsIntrusivePointer::use_count ( ) const
inlinenoexcept

Returns the reference count stored in the object the current CsIntrusivePointer is pointing to.

Friends And Related Function Documentation

CsIntrusivePointer< T > const_pointer_cast ( const CsIntrusivePointer< U > &  ptr)
related

Returns a CsIntrusivePointer which points to the same object as ptr. The intrusive pointer is cast from type T to type U using a const_cast.

See also
dynamic_pointer_cast(), static_pointer_cast()
CsIntrusivePointer< T > const_pointer_cast ( CsIntrusivePointer< U > &&  ptr)
related

Returns a CsIntrusivePointer by moving from ptr. The intrusive pointer is cast from type T to type U using a const_cast.

See also
dynamic_pointer_cast(), static_pointer_cast()
enum CsIntrusiveAction ( )
related

An enum used to indicate what action the Policy class should take if the reference count reaches zero during the current operation.

Constant Value Description
CsIntrusiveAction::Normal 0 Deletes the object when the reference count becomes zero
CsIntrusiveAction::NoDelete 1 Does nothing when the reference count becomes zero
CsIntrusivePointer< T > dynamic_pointer_cast ( const CsIntrusivePointer< U > &  ptr)
related

Returns a CsIntrusivePointer which points to the same object as ptr. The returned intrusive pointer is cast from type T to type U using a dynamic_cast. If the cast fails this method will return a nullptr.

The U must have the same cv-qualifiers (const and volatile) that T has. If you need to cast away either of these qualifiers then use const_pointer_cast().

See also
const_pointer_cast(), static_pointer_cast()
CsIntrusivePointer< T > dynamic_pointer_cast ( CsIntrusivePointer< U > &&  ptr)
related

Returns a CsIntrusivePointer by moving from ptr. The returned intrusive pointer is cast from type T to type U using a dynamic_cast. If the cast fails this method will return a nullptr.

The U must have the same cv-qualifiers (const and volatile) that T has. If you need to cast away either of these qualifiers then use const_pointer_cast().

See also
const_pointer_cast(), static_pointer_cast()
CsIntrusivePointer< T > make_intrusive ( Args &&...  args)
related

This function constructs a new object of type T and returns a intrusive pointer to the newly created object in a single operation.

CsPointer::CsIntrusivePointer<MyFileClass> filePtr = CsPointer::make_intrusive<MyFileClass>( myFileName.path() );
bool operator!= ( const CsIntrusivePointer< T > &  ptr1,
std::nullptr_t   
)
related

Returns true if ptr1 is not a nullptr, otherwise returns false.

bool operator!= ( const CsIntrusivePointer< T1 > &  ptr1,
const CsIntrusivePointer< T2 > &  ptr2 
)
related

Returns true if ptr1 and ptr2 do not point to the same object.

bool operator!= ( const CsIntrusivePointer< T1 > &  ptr1,
const T2 *  ptr2 
)
related

Returns true if ptr1 and ptr2 do not point to the same object.

bool operator!= ( const T1 *  ptr1,
const CsIntrusivePointer< T2 > &  ptr2 
)
related

Returns true if ptr1 and ptr2 do not point to the same object.

bool operator!= ( std::nullptr_t  ,
const CsIntrusivePointer< T > &  ptr2 
)
related

Returns true if ptr2 is not a nullptr, otherwise returns false.

bool operator< ( const CsIntrusivePointer< T1 > &  ptr1,
const CsIntrusivePointer< T2 >  ptr2 
)
related

Returns true if the value of ptr1 is less than ptr2.

bool operator<= ( const CsIntrusivePointer< T1 > &  ptr1,
const CsIntrusivePointer< T2 >  ptr2 
)
related

Returns true if the value of ptr1 is less than or equal to ptr2.

bool operator== ( const CsIntrusivePointer< T > &  ptr1,
std::nullptr_t   
)
related

Returns true if ptr1 is a nullptr, otherwise returns false.

bool operator== ( const CsIntrusivePointer< T1 > &  ptr1,
const CsIntrusivePointer< T2 > &  ptr2 
)
related

Returns true if ptr1 and ptr2 point to the same object.

bool operator== ( const CsIntrusivePointer< T1 > &  ptr1,
const T2 *  ptr2 
)
related

Returns true if ptr1 and ptr2 point to the same object.

bool operator== ( const T1 *  ptr1,
const CsIntrusivePointer< T2 > &  ptr2 
)
related

Returns true if ptr1 and ptr2 point to the same object.

bool operator== ( std::nullptr_t  ,
const CsIntrusivePointer< T > &  ptr2 
)
related

Returns true if ptr2 is a nullptr, otherwise returns false.

bool operator> ( const CsIntrusivePointer< T1 > &  ptr1,
const CsIntrusivePointer< T2 >  ptr2 
)
related

Returns true if the value of ptr1 is greater than ptr2.

bool operator>= ( const CsIntrusivePointer< T1 > &  ptr1,
const CsIntrusivePointer< T2 >  ptr2 
)
related

Returns true if the value of ptr1 is greater than or equal to ptr2.

CsIntrusivePointer< T > static_pointer_cast ( const CsIntrusivePointer< U > &  ptr)
related

Returns a CsIntrusivePointer which points to the same object as ptr. The returned intrusive pointer is cast from type T to type U using a static_cast.

See also
const_pointer_cast(), dynamic_pointer_cast()
CsIntrusivePointer< T > static_pointer_cast ( CsIntrusivePointer< U > &&  ptr)
related

Returns a CsIntrusivePointer by moving from ptr. The returned intrusive pointer is cast from type T to type U using a static_cast.

See also
const_pointer_cast(), dynamic_pointer_cast()
void swap ( CsIntrusivePointer< T > &  ptr1,
CsIntrusivePointer< T > &  ptr2 
)
related

Swaps the value of ptr1 with the value of ptr2.