#ifndef NODETREE_H #define NODETREE_H #ifndef NULL #define NULL ((void*)0) #endif #include #include #include #include "util.h" template class NodeTree { public: NodeTree(); NodeTree(std::string name, T inData); ~NodeTree(); bool const operator==(NodeTree &other); bool const operator<(const NodeTree &other) const; void setParent(NodeTree* parent); void addParent(NodeTree* parent); NodeTree* getParent(); std::vector*> getParents(); void addChild(NodeTree* child); void insertChild(int i, NodeTree* child); void addChildren(std::vector*>* children); void addChildren(std::vector*> children); void insertChildren(int index, std::vector*>* children); void insertChildren(int index, std::vector*> children); int findChild(NodeTree* child); void removeChild(NodeTree* child); void removeChild(int index); void clearChildren(); std::vector*> getChildren(); NodeTree* get(int index); std::string getName(); void setName(std::string); T getData() const; T* getDataRef(); void setData(T data); int size(); std::string DOTGraphString(); private: std::string DOTGraphStringHelper(std::vector*> avoidList); std::string getDOTName(); std::string name; T data; std::vector*> parents; std::vector*> children; static int idCounter; int id; }; template int NodeTree::idCounter; template NodeTree::NodeTree() { name = "UnnamedNode"; id = idCounter++; } template NodeTree::NodeTree(std::string name, T inData) { this->name = name; this->data = inData; id = idCounter++; } template NodeTree::~NodeTree() { children.clear(); parents.clear(); //? Will this segfault? } template const bool NodeTree::operator==(NodeTree &other) { if (!(data == other.data)) return false; if (children.size() != other.getChildren().size()) return false; for (typename std::vector*>::size_type i = 0; i < children.size(); i++) if (! (*(children[i]) == *(other.getChildren()[i]))) return false; return true; } //Used when making a map of NodeTrees template const bool NodeTree::operator<(const NodeTree &other) const { return data < other.getData(); } template void NodeTree::setParent(NodeTree* parent) { parents.clear(); parents.push_back(parent); } template void NodeTree::addParent(NodeTree* parent) { parents.push_back(parent); } template NodeTree* NodeTree::getParent() { if (parents.size() > 0) return parents[0]; return NULL; } template std::vector*> NodeTree::getParents() { return parents; } template void NodeTree::addChild(NodeTree* child) { if (!child) throw "Help, NULL child"; //if (findChild(child) == -1) children.push_back(child); } template void NodeTree::insertChild(int i, NodeTree* child) { if (!child) throw "Help, NULL child"; //if (findChild(child) == -1) children.insert(children.begin()+i,child); } template void NodeTree::addChildren(std::vector*>* children) { for (typename std::vector*>::size_type i = 0; i < children->size(); i++) addChild((*children)[i]); } template void NodeTree::addChildren(std::vector*> children) { for (typename std::vector*>::size_type i = 0; i < children.size(); i++) addChild(children[i]); } template void NodeTree::insertChildren(int index, std::vector*>* children) { for (typename std::vector*>::size_type i = 0; i < children->size(); i++) insertChild(index+i,(*children)[i]); } template void NodeTree::insertChildren(int index, std::vector*> children) { for (typename std::vector*>::size_type i = 0; i < children.size(); i++) insertChild(index+i, children[i]); } template int NodeTree::findChild(NodeTree* child) { for (int i = 0; i < children.size(); i++) { if (children[i] == child) { return i; } } return -1; } template void NodeTree::removeChild(int index) { children[index] = NULL; children.erase(children.begin()+index); } template void NodeTree::removeChild(NodeTree* child) { int index = findChild(child); if (index != -1) { removeChild(index); } } template void NodeTree::clearChildren() { for (typename std::vector::size_type i = 0; i < children.size(); i++) children[i] = NULL; children.clear(); } template std::vector*> NodeTree::getChildren() { return children; } template int NodeTree::size() { int count = 0; for (int i = 0; i < children.size(); i++) { count += children[i]->size(); } return 1+count; } template NodeTree* NodeTree::get(int index) { return children[index]; } template std::string NodeTree::getName() { return name; } template void NodeTree::setName(std::string name) { this->name = name; } template T NodeTree::getData() const { return data; } template T* NodeTree::getDataRef() { return &data; } template void NodeTree::setData(T data) { this->data = data; } template std::string NodeTree::DOTGraphString() { return( "digraph Kraken { \n" + DOTGraphStringHelper(std::vector*>()) + "}"); } template std::string NodeTree::DOTGraphStringHelper(std::vector*> avoidList) { for (typename std::vector*>::size_type i = 0; i < avoidList.size(); i++) if (this == avoidList[i]) return ""; avoidList.push_back(this); std::string ourDOTRelation = ""; for (int i = 0; i < children.size(); i++) { if (children[i] != NULL) ourDOTRelation += getDOTName() + " -> " + children[i]->getDOTName() + ";\n" + children[i]->DOTGraphStringHelper(avoidList); else ourDOTRelation += getDOTName() + " -> BAD_NULL_" + getDOTName() + "\n"; } return(ourDOTRelation); } template std::string NodeTree::getDOTName() { std::string DOTName = ""; DOTName = "\"" + replaceExEscape(name + "-" + data.toString(), "\"", "\\\"") + "_" + intToString(id) + "\""; //Note that terminals already have a quote in the front of their name, so we don't need to add one // if (data != NULL) // DOTName = "\"" + replaceExEscape(name + "-" + data->toString(), "\"", "\\\"") + "_" + intToString(id) + "\""; //Note that terminals already have a quote in the front of their name, so we don't need to add one // else // DOTName = "\"" + replaceExEscape(name, "\"", " \\\"") + "_" + intToString(id) + "\""; return(replaceExEscape(DOTName, "\n", "\\n")); } #endif