New TreeNode methods

This commit is contained in:
Léa Saviot
2018-06-22 11:49:24 +02:00
parent 2908c20def
commit 0fb04ea45a
4 changed files with 91 additions and 5 deletions

View File

@@ -6,7 +6,7 @@
class ExpressionNode : public TreeNode {
public:
virtual float approximate() = 0;
ExpressionNode * child(int i) { return static_cast<ExpressionNode *>(treeChildAtIndex(i)); }
ExpressionNode * child(int i) { return static_cast<ExpressionNode *>(childTreeAtIndex(i)); }
};
#endif

View File

@@ -2,7 +2,7 @@
#include "tree_pool.h"
#include "expression_node.h"
TreeNode * TreeNode::treeParent() const {
TreeNode * TreeNode::parentTree() const {
// Choose between those two algorithms: the first has complexity O(numberNodes) but uses 0(3maxNumberNodes) space
// The second is much clearer for the reader and uses no space, but has complexity 0
#if 0
@@ -46,6 +46,16 @@ TreeNode * TreeNode::treeParent() const {
#endif
}
TreeNode * TreeNode::editableRootTree() {
for (TreeNode * root : TreePool::sharedPool()->roots()) {
if (hasAncestor(root, true)) {
return root;
}
}
assert(false);
return nullptr;
}
int TreeNode::numberOfDescendants(bool includeSelf) const {
int result = includeSelf ? 1 : 0;
for (TreeNode * child : depthFirstChildren()) {
@@ -54,7 +64,7 @@ int TreeNode::numberOfDescendants(bool includeSelf) const {
return result;
}
TreeNode * TreeNode::treeChildAtIndex(int i) const {
TreeNode * TreeNode::childTreeAtIndex(int i) const {
assert(i >= 0);
assert(i < numberOfChildren());
TreeNode * child = next();
@@ -66,6 +76,60 @@ TreeNode * TreeNode::treeChildAtIndex(int i) const {
return child;
}
int TreeNode::indexOfChild(const TreeNode * child) const {
if (child == nullptr) {
return -1;
}
int childrenCount = numberOfChildren();
TreeNode * childAtIndexi = next();
for (int i = 0; i < childrenCount; i++) {
if (childAtIndexi == child) {
return i;
}
childAtIndexi = childAtIndexi->nextSibling();
}
return -1;
}
bool TreeNode::hasChild(const TreeNode * child) const {
if (child == nullptr) {
return false;
}
for (TreeNode * c : directChildren()) {
if (child == c) {
return true;
}
}
return false;
}
bool TreeNode::hasAncestor(const TreeNode * node, bool includeSelf) const {
if (includeSelf && node == this) {
return true;
}
for (TreeNode * t : node->depthFirstChildren()) {
if (this == t) {
return true;
}
}
return false;
}
bool TreeNode::hasSibling(const TreeNode * e) const {
if (e == nullptr) {
return false;
}
TreeNode * parent = parentTree();
if (parent == nullptr) {
return false;
}
for (TreeNode * childNode : parent->directChildren()) {
if (childNode == e) {
return true;
}
}
return false;
}
void TreeNode::release() {
printf("Release %d(%p)\n", m_identifier, this);

View File

@@ -40,11 +40,15 @@ public:
}
// Hierarchy
TreeNode * treeParent() const;
TreeNode * parentTree() const;
TreeNode * editableRootTree();
virtual int numberOfChildren() const { return 0; }
int numberOfDescendants(bool includeSelf) const;
TreeNode * treeChildAtIndex(int i) const;
TreeNode * childTreeAtIndex(int i) const;
int indexOfChild(const TreeNode * child) const;
bool hasChild(const TreeNode * child) const;
bool hasAncestor(const TreeNode * node, bool includeSelf) const;
bool hasSibling(const TreeNode * e) const;
class Iterator {
public:

View File

@@ -111,6 +111,24 @@ protected:
};
AllPool allNodes() { return AllPool(*(begin())); }
class Roots {
public:
Roots(TreeNode * node) : m_node(node) {}
class Iterator : public TreeNode::Iterator {
public:
using TreeNode::Iterator::Iterator;
Iterator & operator++() {
m_node = m_node->nextSibling();
return *this;
}
};
Iterator begin() const { return Iterator(m_node); }
Iterator end() const { return Iterator(TreePool::sharedPool()->last()); }
private:
TreeNode * m_node;
};
Roots roots() { return Roots(*(begin())); }
TreeNode::DepthFirst::Iterator begin() const { return TreeNode::DepthFirst::Iterator(first()); }
TreeNode::DepthFirst::Iterator end() const { return TreeNode::DepthFirst::Iterator(last()); }