mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-29 03:29:58 +02:00
New TreeNode methods
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
18
tree_pool.h
18
tree_pool.h
@@ -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()); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user