ReplaceWith and ReplaceChild methods on References

This commit is contained in:
Léa Saviot
2018-06-22 14:05:23 +02:00
parent 0fb04ea45a
commit 6f598acc10
5 changed files with 81 additions and 63 deletions

View File

@@ -25,6 +25,14 @@ public:
TreeReference<T>::addChild(e);
}
ExpressionReference<ExpressionNode> childAtIndex(int i) {
return TreeReference<T>::childAtIndex(i);
}
void replaceChildAtIndex(int oldChildIndex, ExpressionReference<ExpressionNode> newChild) {
TreeReference<T>::replaceChildAtIndex(oldChildIndex, newChild);
}
float approximate() const {
return this->node()->approximate();
}

View File

@@ -2,7 +2,7 @@
#include "addition_node.h"
#include <stdio.h>
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();

View File

@@ -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);
}
}

View File

@@ -1,14 +0,0 @@
#include "tree_reference.h"
#if 0
void TreeReference::addOperand(TreeReference<TreeNode> 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

View File

@@ -9,7 +9,7 @@ template <class T>
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<const TreeReference<TreeNode> *>(this));
}
int numberOfChildren() const {
return node()->numberOfChildren();
}
TreeReference<T> childAtIndex(int i) const {
return TreeReference(node()->childAtIndex(i));
}
void addChild(TreeReference<TreeNode> t) {
TreeNode * deepCopy = TreePool::sharedPool()->deepCopy(t.node());
TreePool::sharedPool()->move(
deepCopy,
node()->next()
);
}
void removeChild(TreeReference<TreeNode> 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<T*>(TreePool::sharedPool()->node(m_identifier));
@@ -59,6 +35,43 @@ public:
int identifier() const { return m_identifier; }
// Hierarchy
int numberOfChildren() const {
return node()->numberOfChildren();
}
TreeReference<T> parent() const {
return TreeReference(node()->parentTree());
}
TreeReference<T> childAtIndex(int i) const {
return TreeReference(node()->child(i));
}
// Hierarchy operations
void addChild(TreeReference<TreeNode> t) {
TreeNode * deepCopy = TreePool::sharedPool()->deepCopy(t.node());
TreePool::sharedPool()->move(deepCopy, node()->next());
}
void removeChild(TreeReference<TreeNode> t) {
TreePool::sharedPool()->move(t.node(), TreePool::sharedPool()->last());
t.node()->release();
}
void replaceWith(TreeReference<TreeNode> t) {
parent().replaceChild(node()->indexOfChild(t.node()), t);
}
void replaceChildAtIndex(int oldChildIndex, TreeReference<TreeNode> newChild) {
assert(oldChildIndex >= 0 && oldChildIndex < numberOfChildren());
TreeReference<T> 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<T>();