casacore
Loading...
Searching...
No Matches
Classes | Public Member Functions | Private Member Functions | Private Attributes | Friends | List of all members
casacore::details::CyclicPtr< T > Class Template Reference

A smart pointer class that allows to work with complex cycles without using weak_ptrs. More...

#include <CyclicPtr.h>

Classes

struct  Data
 

Public Member Functions

 CyclicPtr ()=default
 
 CyclicPtr (std::nullptr_t)
 
 CyclicPtr (T *object)
 
 CyclicPtr (const CyclicPtr &source)
 
 CyclicPtr (CyclicPtr &&source)
 
 ~CyclicPtr ()
 
T * Get () const
 
void Reset ()
 
CyclicPtroperator= (const CyclicPtr &other)
 
CyclicPtroperator= (CyclicPtr &&other)
 
 operator bool () const
 
T & operator* () const
 
T * operator-> () const
 
CyclicState Freeze () const
 Freeze the reference counter.
 
void Unfreeze (const CyclicState &frozen_state)
 Continue 'normal' reference counting.
 

Private Member Functions

void Increase ()
 
void Decrease ()
 

Private Attributes

std::shared_ptr< Datadata_
 

Friends

bool operator== (const CyclicPtr< T > &lhs, const CyclicPtr< T > &rhs)
 
bool operator!= (const CyclicPtr< T > &lhs, const CyclicPtr< T > &rhs)
 

Detailed Description

template<typename T>
class casacore::details::CyclicPtr< T >

A smart pointer class that allows to work with complex cycles without using weak_ptrs.

Instead, the pointer needs to be manually frozen during the creation of cycles, such that cycle-links are not counted.

This class was specifically written for the MeasFrame class, which can have cycles via various routes. Originally, the FrameRep class held a counter and was destructed when the counter reached zero. While this worked, it had issues:

Having a separate class that also holds the counter avoids these problems. Introducing weak_ptrs to break the cycles in the measures code has been tried, but probably requires major changes in the structure.

This is an example of how to use the class:

struct Node { CyclicPtr<Node> link; };

CyclicPtr<Node> node = MakeCyclic<Node>();
const CyclicState state = node.Freeze();
node->link = node;
node.Unfreeze(state);

By freezing the state when creating the link, the link is not counted as a reference. As soon as either node->link or node is reset or goes out of scope, the Node object is destroyed and the other CyclicPtr will become nullptr.

This class implements the counter in a thread-safe way, such that the pointer can be copied around in different threads as if it is a normal pointer. Freeze() and Unfreeze() are not thread safe. In the MeasFrame class, these functions are only used during initialization or write-to actions of the MeasFrame, which remains valid.

It should be clear that this is a dangerous class to use correctly.

Definition at line 78 of file CyclicPtr.h.

Constructor & Destructor Documentation

◆ CyclicPtr() [1/5]

template<typename T >
casacore::details::CyclicPtr< T >::CyclicPtr ( )
default

◆ CyclicPtr() [2/5]

template<typename T >
casacore::details::CyclicPtr< T >::CyclicPtr ( std::nullptr_t  )
inline

Definition at line 83 of file CyclicPtr.h.

◆ CyclicPtr() [3/5]

template<typename T >
casacore::details::CyclicPtr< T >::CyclicPtr ( T *  object)
inlineexplicit

Definition at line 85 of file CyclicPtr.h.

◆ CyclicPtr() [4/5]

template<typename T >
casacore::details::CyclicPtr< T >::CyclicPtr ( const CyclicPtr< T > &  source)
inline

Definition at line 88 of file CyclicPtr.h.

References casacore::details::CyclicPtr< T >::Increase().

◆ CyclicPtr() [5/5]

template<typename T >
casacore::details::CyclicPtr< T >::CyclicPtr ( CyclicPtr< T > &&  source)
inline

Definition at line 93 of file CyclicPtr.h.

◆ ~CyclicPtr()

template<typename T >
casacore::details::CyclicPtr< T >::~CyclicPtr ( )
inline

Definition at line 96 of file CyclicPtr.h.

References casacore::details::CyclicPtr< T >::Decrease().

Member Function Documentation

◆ Decrease()

template<typename T >
void casacore::details::CyclicPtr< T >::Decrease ( )
inlineprivate

◆ Freeze()

template<typename T >
CyclicState casacore::details::CyclicPtr< T >::Freeze ( ) const
inline

Freeze the reference counter.

The object is guaranteed not to be destructed until Unfreeze() is called.

The caller is responsible for calling Unfreeze(); letting CyclicState go out of scope without unfreezing will not cause an error, so will lead to an undetected state error. While it would be possible to detect this, it would increase the size of CyclicState.

Definition at line 144 of file CyclicPtr.h.

References casacore::details::CyclicPtr< T >::data_.

◆ Get()

template<typename T >
T * casacore::details::CyclicPtr< T >::Get ( ) const
inline

Definition at line 100 of file CyclicPtr.h.

References casacore::details::CyclicPtr< T >::data_.

◆ Increase()

template<typename T >
void casacore::details::CyclicPtr< T >::Increase ( )
inlineprivate

◆ operator bool()

template<typename T >
casacore::details::CyclicPtr< T >::operator bool ( ) const
inlineexplicit

Definition at line 122 of file CyclicPtr.h.

References casacore::details::CyclicPtr< T >::data_.

◆ operator*()

template<typename T >
T & casacore::details::CyclicPtr< T >::operator* ( ) const
inline

Definition at line 124 of file CyclicPtr.h.

References casacore::details::CyclicPtr< T >::data_.

◆ operator->()

template<typename T >
T * casacore::details::CyclicPtr< T >::operator-> ( ) const
inline

Definition at line 125 of file CyclicPtr.h.

References casacore::details::CyclicPtr< T >::data_.

◆ operator=() [1/2]

template<typename T >
CyclicPtr & casacore::details::CyclicPtr< T >::operator= ( const CyclicPtr< T > &  other)
inline

◆ operator=() [2/2]

template<typename T >
CyclicPtr & casacore::details::CyclicPtr< T >::operator= ( CyclicPtr< T > &&  other)
inline

◆ Reset()

template<typename T >
void casacore::details::CyclicPtr< T >::Reset ( )
inline

◆ Unfreeze()

template<typename T >
void casacore::details::CyclicPtr< T >::Unfreeze ( const CyclicState frozen_state)
inline

Continue 'normal' reference counting.

Definition at line 151 of file CyclicPtr.h.

References casacore::details::CyclicPtr< T >::data_, and casacore::details::CyclicState::value_.

Friends And Related Symbol Documentation

◆ operator!=

template<typename T >
bool operator!= ( const CyclicPtr< T > &  lhs,
const CyclicPtr< T > &  rhs 
)
friend

Definition at line 131 of file CyclicPtr.h.

◆ operator==

template<typename T >
bool operator== ( const CyclicPtr< T > &  lhs,
const CyclicPtr< T > &  rhs 
)
friend

Definition at line 127 of file CyclicPtr.h.

Member Data Documentation

◆ data_

template<typename T >
std::shared_ptr<Data> casacore::details::CyclicPtr< T >::data_
private

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