From 0fb04ea45a384c1d487b6abf4f852ea7f8d4d81a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 22 Jun 2018 11:49:24 +0200 Subject: [PATCH] New TreeNode methods --- expression_node.h | 2 +- tree_node.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++-- tree_node.h | 8 ++++-- tree_pool.h | 18 +++++++++++++ 4 files changed, 91 insertions(+), 5 deletions(-) diff --git a/expression_node.h b/expression_node.h index 433bb5ce7..6512d864c 100644 --- a/expression_node.h +++ b/expression_node.h @@ -6,7 +6,7 @@ class ExpressionNode : public TreeNode { public: virtual float approximate() = 0; - ExpressionNode * child(int i) { return static_cast(treeChildAtIndex(i)); } + ExpressionNode * child(int i) { return static_cast(childTreeAtIndex(i)); } }; #endif diff --git a/tree_node.cpp b/tree_node.cpp index 2499511e1..034ef3aac 100644 --- a/tree_node.cpp +++ b/tree_node.cpp @@ -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); diff --git a/tree_node.h b/tree_node.h index 74b413618..f8f6f815e 100644 --- a/tree_node.h +++ b/tree_node.h @@ -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: diff --git a/tree_pool.h b/tree_pool.h index b8b981a27..5a744fc73 100644 --- a/tree_pool.h +++ b/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()); }