|
| 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 |
|
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.
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>
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);
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.