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

Manages a container of intrusive pointers. More...

Public Typedefs

using size_type = typename std::vector< CsIntrusivePointer< T, Policy > >::size_type
 

Public Member Functions

 CsNodeManager () = default
 
virtual ~CsNodeManager ()
 
 CsNodeManager (const CsNodeManager &other) = default
 
CsNodeManager & operator= (const CsNodeManager &other) = default
 
 CsNodeManager (CsNodeManager &&other) = default
 
CsNodeManager & operator= (CsNodeManager &&other) = default
 
void add_child (T *child)
 
void add_child (CsIntrusivePointer< T, Policy > child)
 
const std::vector< CsIntrusivePointer< T, Policy > > & children () const
 
void clear ()
 
template<typename U >
CsIntrusivePointer< U, Policy > find_child () const
 
template<typename U , typename F >
CsIntrusivePointer< U, Policy > find_child (const F &lambda) const
 
template<typename U >
std::vector< CsIntrusivePointer< U, Policy > > find_children () const
 
template<typename U , typename F >
std::vector< CsIntrusivePointer< U, Policy > > find_children (const F &lambda) const
 
void move_child (size_type source, size_type dest)
 
bool remove_child (T *child)
 
bool remove_child (const CsIntrusivePointer< T, Policy > &child)
 
template<typename U = T, typename F >
VisitStatus visit (const F &lambda, VisitChildren option=VisitChildren::Recursive) const
 

Related Functions

These are not member functions

enum VisitChildren
 
enum VisitStatus
 

Detailed Description

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

The CsNodeManager class manages an internal container of intrusive pointers. Each element in the container refers to an existing child object. The purpose of this class is manage the lifetime of the child objects stored in the current node.

A child object is added to the current node by passing an intrusive pointer or a raw pointer. If a raw pointer is passed a new intrusive pointer will be instantiated. When an element in the current node is removed from the internal container, the reference count for the object it points to is decremented. If the reference count is now zero the child object will be deleted.

  • If the object is deleted then any existing raw pointers are now invalid and dereferencing them will be undefined behavior.
  • If an element is removed from the node manager and there are existing intrusive pointers, the object will not be deleted since the reference count will not be zero. These intrusive pointers remain valid.

The reference count for an intrusive pointer is maintained in the CsIntrusiveBase class and not in the intrusive pointer object or a separate control block. In order to use the node manager your base class must inherit from both CsNodeManager and CsIntrusiveBase as shown below.

class MyClass : public CsPointer::CsNodeManager<MyClass>, public CsPointer::CsIntrusiveBase

Example

In the following example child_1 and child_2 are added to the node manager of rootObj. The intrusive pointer for child_3 is added as a grand child of rootObj and a child of child_1.

template <typename T>
using IntrusivePtr = CsPointer::CsIntrusivePointer<T>;
IntrusivePtr<Widget> rootObj = CsPointer::make_intrusive<Widget>();
IntrusivePtr<Widget> child_1 = CsPointer::make_intrusive<Widget>();
IntrusivePtr<Widget> child_2 = CsPointer::make_intrusive<Widget>();
IntrusivePtr<Widget> child_3 = CsPointer::make_intrusive<Widget>();
rootObj->add_child(child_1);
rootObj->add_child(child_2);
child_1->add_child(child_3);

Member Typedef Documentation

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsNodeManager::size_type

Typedef for std::vector<CsIntrusivePointer<T, Policy>>::size_type.

Constructor & Destructor Documentation

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsNodeManager::CsNodeManager ( )
default

Creates a new CsNodeManager.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsNodeManager::~CsNodeManager ( )
inlinevirtual

Virtual destructor which does nothing.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsNodeManager::CsNodeManager ( const CsNodeManager< T, Policy > &  other)
default

Copy constructs a new CsNodeManager from other.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsNodeManager::CsNodeManager ( CsNodeManager< T, Policy > &&  other)
default

Move constructs a new CsNodeManager from other.

Member Function Documentation

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
void CsNodeManager::add_child ( CsIntrusivePointer< T, Policy >  child)
inline

Adds the given child to the internal container of children.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
void CsNodeManager::add_child ( T *  child)
inline

Converts the raw pointer child to a CsIntrusivePointer<T, Policy> and then adds it to the internal container of children.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
const std::vector< CsIntrusivePointer< T, Policy > > & CsNodeManager::children ( ) const
inline

Returns a read only reference to the internal container of intrusive pointers.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
void CsNodeManager::clear ( )
inline

Removes all elements from the internal container and automatically calls the destructor for the given object if the reference count becomes zero.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
template<typename U >
CsIntrusivePointer< U, Policy > CsPointer::CsNodeManager< T, Policy >::find_child ( ) const

Returns the first child which can be dynamically cast to type U. If there no match then a nullptr is returned. If an element has children the search will continue in the container for that child.

template<typename T , typename Policy >
template<typename U , typename F >
CsIntrusivePointer< U, Policy > CsPointer::CsNodeManager< T, Policy >::find_child ( const F &  lambda) const

Returns the first child which can be dynamically cast to type U and the given lambda expression evaluates to true. If there no match then a nullptr is returned. If an element has children the search will continue in the container for that child.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
template<typename U >
std::vector< CsIntrusivePointer< U, Policy > > CsPointer::CsNodeManager< T, Policy >::find_children ( ) const

Returns all children of this object which can be cast to type U. Returns an empty vector if there are no such objects. If an element has children the search will continue in the container for that child.

template<typename T , typename Policy >
template<typename U , typename F >
std::vector< CsIntrusivePointer< U, Policy > > CsPointer::CsNodeManager< T, Policy >::find_children ( const F &  lambda) const

Returns all of the children which can be cast to type U and the evaluation of the lambda returns true. Returns an empty vector if there are no such objects. If an element has children the search will continue in the container for that child.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
void CsNodeManager::move_child ( size_type  source,
size_type  dest 
)
inline

Moves the element at source to the dest position in the internal container of children.

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

Copy assigns from other and returns a reference to this object.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
CsNodeManager & CsNodeManager::operator= ( CsNodeManager< T, Policy > &&  other)
default

Move assigns from other and returns a reference to this object.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
bool CsNodeManager::remove_child ( const CsIntrusivePointer< T, Policy > &  child)
inline

Removes the first element matching the given child from the internal container of children. The destructor for this element will be invoked if the reference count becomes zero.

template<typename T , typename Policy = CsIntrusiveDefaultPolicy>
bool CsNodeManager::remove_child ( T *  child)
inline

Converts the raw pointer child to a CsIntrusivePointer<T, Policy>. Removes the first element matching child from the internal container of children. The destructor for this element will be invoked if the reference count becomes zero.

template<typename T , typename Policy >
template<typename U , typename F >
VisitStatus CsPointer::CsNodeManager< T, Policy >::visit ( const F &  lambda,
VisitChildren  option = VisitChildren::Recursive 
) const

Invokes the lambda for every element in the current internal container of children. If the value of option is VisitChildren::Recursive then child objects of the current element will be visited. Processing will then resume with the next element in the original node container.

The enum VisitStatus is used to determine if processing should proceed or terminate. Your lambda expression must return either VisitStatus::VisitMore or VisitStatus::Finished.

Friends And Related Function Documentation

enum VisitChildren ( )
related

This enum defines whether the visit() method should process the objects in child nodes.

Constant Value Description
VisitChildren::Recursive 0 Visit children and grand-children in all nodes
VisitChildren::NonRecursive 1 Only visit children in the current node
enum VisitStatus ( )
related

This enum is used in the visit() method to determine if processing should continue. The lambda expression passed to visit() must return one of the enum values.

Constant Value Description
VisitStatus::VisitMore 0 Continue processing
VisitStatus::Finished 1 Stop processing