Files
Upsilon/tree_node.h
2018-06-22 15:07:24 +02:00

181 lines
4.0 KiB
C++

#ifndef TREE_NODE_H
#define TREE_NODE_H
#include <assert.h>
#include <stddef.h>
#include <strings.h>
#define TREE_LOGGING 1
#include <stdio.h>
/* What's in a TreeNode, really?
* - a vtable
* - an identifier
* - a reference counter
*/
class TreeNode {
//friend class TreeReference;
// friend class TreePool;
public:
virtual ~TreeNode() {
}
// Iterators
class Iterator {
public:
Iterator(TreeNode * node) : m_node(node) {}
TreeNode * operator*() { return m_node; }
bool operator!=(const Iterator& it) const { return (m_node != it.m_node); }
protected:
TreeNode * m_node;
};
class Direct {
public:
Direct(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->next()); }
Iterator end() const { return Iterator(m_node->nextSibling()); }
private:
TreeNode * m_node;
};
Direct directChildren() { return Direct(this); }
class DepthFirst {
public:
DepthFirst(TreeNode * node) : m_node(node) {}
class Iterator : public TreeNode::Iterator {
public:
using TreeNode::Iterator::Iterator;
Iterator & operator++() {
m_node = m_node->next();
return *this;
}
};
Iterator begin() const { return Iterator(m_node->next()); }
Iterator end() const { return Iterator(m_node->nextSibling()); }
private:
TreeNode * m_node;
};
DepthFirst depthFirstChildren() { return DepthFirst(this); }
int identifier() const { return m_identifier; }
#if TREE_LOGGING
virtual const char * description() const {
return "UNKNOWN";
}
#endif
virtual size_t size() const { // Consider making this full abstract?
return sizeof(TreeNode);
}
void retain() {
m_referenceCounter++;
}
void release();
void rename(int identifier) {
m_identifier = identifier;
m_referenceCounter = 1;
}
int retainCount() {
return m_referenceCounter;
}
virtual int numberOfChildren() const {
return 0;
}
TreeNode * childAtIndex(int i) const {
assert(i >= 0);
assert(i < numberOfChildren());
TreeNode * child = next();
while (i > 0) {
child = child->nextSibling();
assert(child != nullptr);
i--;
}
return child;
}
//private:
// FIXME: Make this private
TreeNode(int identifier) :
m_identifier(identifier),
m_referenceCounter(1)
{
}
TreeNode * next() const {
// Simple version would be "return this + 1;", with pointer arithmetics taken care of by the compiler.
// Unfortunately, we want TreeNode to have a VARIABLE size
return reinterpret_cast<TreeNode *>(reinterpret_cast<char *>(const_cast<TreeNode *>(this)) + size());
}
TreeNode * nextSibling() const {
int remainingNodesToVisit = numberOfChildren();
TreeNode * node = const_cast<TreeNode *>(this)->next();
while (remainingNodesToVisit > 0) {
remainingNodesToVisit += node->numberOfChildren();
node = node->next();
remainingNodesToVisit--;
}
return node;
}
/*TreeNode * lastDescendant() const {
TreeNode * node = const_cast<TreeNode *>(this);
int remainingNodesToVisit = node->numberOfChildren();
while (remainingNodesToVisit > 0) {
node = node->next();
remainingNodesToVisit--;
remainingNodesToVisit += node->numberOfChildren();
}
return node;
}*/
TreeNode * lastChild() const {
if (numberOfChildren() == 0) {
return const_cast<TreeNode *>(this);
}
TreeNode * node = next();
for (int i = 0; i < numberOfChildren() - 1; i++) {
node = node->nextSibling();
}
return node;
}
size_t deepSize() const {
// TODO: Error handling
return
reinterpret_cast<char *>(nextSibling())
-
reinterpret_cast<const char *>(this);
;
}
//private:
int m_identifier;
int m_referenceCounter;
};
#endif