From 6f598acc10b0ead5cb4736c03415f9e9cfcf2d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 22 Jun 2018 14:05:23 +0200 Subject: [PATCH] ReplaceWith and ReplaceChild methods on References --- expression_reference.h | 8 ++++++ test.cpp | 11 ++++++-- tree_node.cpp | 48 +++++++++++++++++--------------- tree_reference.cpp | 14 ---------- tree_reference.h | 63 +++++++++++++++++++++++++----------------- 5 files changed, 81 insertions(+), 63 deletions(-) delete mode 100644 tree_reference.cpp diff --git a/expression_reference.h b/expression_reference.h index 75c53f3d7..072699f71 100644 --- a/expression_reference.h +++ b/expression_reference.h @@ -25,6 +25,14 @@ public: TreeReference::addChild(e); } + ExpressionReference childAtIndex(int i) { + return TreeReference::childAtIndex(i); + } + + void replaceChildAtIndex(int oldChildIndex, ExpressionReference newChild) { + TreeReference::replaceChildAtIndex(oldChildIndex, newChild); + } + float approximate() const { return this->node()->approximate(); } diff --git a/test.cpp b/test.cpp index cdbfc143d..2e1d9b637 100644 --- a/test.cpp +++ b/test.cpp @@ -2,7 +2,7 @@ #include "addition_node.h" #include -Expression buildAddition() { +Addition buildAddition() { printf("\n\n-----------------------------\n"); printf("CODE: Float smallFloat(0.2f);\n\n"); Float smallFloat(0.2f); @@ -24,7 +24,14 @@ Expression buildAddition() { int main() { printf("\n\n-----------------------------\n"); printf("CODE: Expression a = buildAddition();\n\n"); - Expression a = buildAddition(); + Addition a = buildAddition(); + float result = a.approximate(); + printf("a = %f \n", result); + Float smallFloat(1.3f); + a.replaceChildAtIndex(0, smallFloat); + float result2 = a.approximate(); + printf("a = %f \n", result2); + printf("HAS RETURNED\n"); TreePool::sharedPool()->log(); diff --git a/tree_node.cpp b/tree_node.cpp index 034ef3aac..f227ca2ef 100644 --- a/tree_node.cpp +++ b/tree_node.cpp @@ -2,6 +2,32 @@ #include "tree_pool.h" #include "expression_node.h" +// Node operations + +void TreeNode::release() { + printf("Release %d(%p)\n", m_identifier, this); + m_referenceCounter--; + if (m_referenceCounter == 0) { + if (numberOfChildren() != 0) { + int lastIdentifier = lastChild()->identifier(); + TreeNode * child = next(); + bool lastChildReleased = false; + while (!lastChildReleased) { + lastChildReleased = child->identifier() == lastIdentifier; + int nextSiblingIdentifier = lastChildReleased ? -1 : child->nextSibling()->identifier(); + child->release(); + if (nextSiblingIdentifier != -1) { + child = TreePool::sharedPool()->node(nextSiblingIdentifier); + } + } + } + printf("Delete %d(%p)\n", m_identifier, this); + TreePool::sharedPool()->discardTreeNode(this); + } +} + +// Hierarchy + 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 @@ -130,25 +156,3 @@ bool TreeNode::hasSibling(const TreeNode * e) const { } return false; } - -void TreeNode::release() { - printf("Release %d(%p)\n", m_identifier, this); - m_referenceCounter--; - if (m_referenceCounter == 0) { - if (numberOfChildren() != 0) { - int lastIdentifier = lastChild()->identifier(); - TreeNode * child = next(); - bool lastChildReleased = false; - while (!lastChildReleased) { - lastChildReleased = child->identifier() == lastIdentifier; - int nextSiblingIdentifier = lastChildReleased ? -1 : child->nextSibling()->identifier(); - child->release(); - if (nextSiblingIdentifier != -1) { - child = TreePool::sharedPool()->node(nextSiblingIdentifier); - } - } - } - printf("Delete %d(%p)\n", m_identifier, this); - TreePool::sharedPool()->discardTreeNode(this); - } -} diff --git a/tree_reference.cpp b/tree_reference.cpp deleted file mode 100644 index e42312dad..000000000 --- a/tree_reference.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "tree_reference.h" - -#if 0 -void TreeReference::addOperand(TreeReference t) { - // At this point, e has been copied. - // We can therefore pilfer its node! - Node * n = node(); - pool->move( - t->node(), - t->next() - ); - node->stealAsOperand(t->node()); -} -#endif diff --git a/tree_reference.h b/tree_reference.h index 97f85a3e8..74a80b119 100644 --- a/tree_reference.h +++ b/tree_reference.h @@ -9,7 +9,7 @@ template class TreeReference { public: TreeReference(const TreeReference & tr) { - int trNodeIdentifier = tr.m_identifier; + int trNodeIdentifier = tr.identifier(); printf("TreeReference copy of %d\n", trNodeIdentifier); TreeNode * nodeCopy = TreePool::sharedPool()->deepCopy(TreePool::sharedPool()->node(trNodeIdentifier)); m_identifier = nodeCopy->identifier(); @@ -28,30 +28,6 @@ public: return *(reinterpret_cast *>(this)); } - int numberOfChildren() const { - return node()->numberOfChildren(); - } - - TreeReference childAtIndex(int i) const { - return TreeReference(node()->childAtIndex(i)); - } - - void addChild(TreeReference t) { - TreeNode * deepCopy = TreePool::sharedPool()->deepCopy(t.node()); - TreePool::sharedPool()->move( - deepCopy, - node()->next() - ); - } - - void removeChild(TreeReference t) { - TreePool::sharedPool()->move( - t.node(), - TreePool::sharedPool()->last() - ); - t.node()->release(); - } - T * node() const { // TODO: Here, assert that the node type is indeed T return static_cast(TreePool::sharedPool()->node(m_identifier)); @@ -59,6 +35,43 @@ public: int identifier() const { return m_identifier; } + // Hierarchy + int numberOfChildren() const { + return node()->numberOfChildren(); + } + + TreeReference parent() const { + return TreeReference(node()->parentTree()); + } + + TreeReference childAtIndex(int i) const { + return TreeReference(node()->child(i)); + } + + // Hierarchy operations + + void addChild(TreeReference t) { + TreeNode * deepCopy = TreePool::sharedPool()->deepCopy(t.node()); + TreePool::sharedPool()->move(deepCopy, node()->next()); + } + + void removeChild(TreeReference t) { + TreePool::sharedPool()->move(t.node(), TreePool::sharedPool()->last()); + t.node()->release(); + } + + void replaceWith(TreeReference t) { + parent().replaceChild(node()->indexOfChild(t.node()), t); + } + + void replaceChildAtIndex(int oldChildIndex, TreeReference newChild) { + assert(oldChildIndex >= 0 && oldChildIndex < numberOfChildren()); + TreeReference oldChild = childAtIndex(oldChildIndex); + TreePool::sharedPool()->move(newChild.node(), oldChild.node()->next()); + newChild.node()->retain(); + TreePool::sharedPool()->move(oldChild.node(), TreePool::sharedPool()->last()); + oldChild.node()->release(); + } protected: TreeReference() { TreeNode * node = TreePool::sharedPool()->createTreeNode();