diff --git a/tree_node.cpp b/tree_node.cpp index e05cc7bc7..2499511e1 100644 --- a/tree_node.cpp +++ b/tree_node.cpp @@ -3,6 +3,9 @@ #include "expression_node.h" TreeNode * TreeNode::treeParent() 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 int cursor = -1; TreeNode * parentsHistory[TreePool::MaxNumberOfNodes]; int numberOfChildrenHistory[TreePool::MaxNumberOfNodes]; @@ -29,6 +32,26 @@ TreeNode * TreeNode::treeParent() const { } assert(false); return nullptr; +#else + for (TreeNode * node : TreePool::sharedPool()->allNodes()) { + if (node == this) { + return nullptr; + } + if (node->hasChild(this)) { + return node; + } + } + assert(false); + return nullptr; +#endif +} + +int TreeNode::numberOfDescendants(bool includeSelf) const { + int result = includeSelf ? 1 : 0; + for (TreeNode * child : depthFirstChildren()) { + result++; + } + return result; } TreeNode * TreeNode::treeChildAtIndex(int i) const { diff --git a/tree_node.h b/tree_node.h index d892f6829..74b413618 100644 --- a/tree_node.h +++ b/tree_node.h @@ -42,11 +42,13 @@ public: // Hierarchy TreeNode * treeParent() const; virtual int numberOfChildren() const { return 0; } + int numberOfDescendants(bool includeSelf) const; TreeNode * treeChildAtIndex(int i) const; + bool hasChild(const TreeNode * child) const; class Iterator { public: - Iterator(TreeNode * node) : m_node(node) {} + Iterator(const TreeNode * node) : m_node(const_cast(node)) {} TreeNode * operator*() { return m_node; } bool operator!=(const Iterator& it) const { return (m_node != it.m_node); } protected: @@ -55,7 +57,7 @@ public: class Direct { public: - Direct(TreeNode * node) : m_node(node) {} + Direct(const TreeNode * node) : m_node(const_cast(node)) {} class Iterator : public TreeNode::Iterator { public: using TreeNode::Iterator::Iterator; @@ -72,7 +74,7 @@ public: class DepthFirst { public: - DepthFirst(TreeNode * node) : m_node(node) {} + DepthFirst(const TreeNode * node) : m_node(const_cast(node)) {} class Iterator : public TreeNode::Iterator { public: using TreeNode::Iterator::Iterator; @@ -87,8 +89,8 @@ public: TreeNode * m_node; }; - Direct directChildren() { return Direct(this); } - DepthFirst depthFirstChildren() { return DepthFirst(this); } + Direct directChildren() const { return Direct(this); } + DepthFirst depthFirstChildren() const { return DepthFirst(this); } TreeNode * next() const { // Simple version would be "return this + 1;", with pointer arithmetics taken care of by the compiler.