2013-05-11 16:13:46 -04:00
# ifndef NODETREE_H
# define NODETREE_H
# ifndef NULL
# define NULL 0
2013-05-20 19:34:15 -04:00
# endif
2013-05-11 16:13:46 -04:00
# include <vector>
# include <string>
2013-06-23 05:54:58 -04:00
# include <iostream>
2013-05-11 16:13:46 -04:00
2013-08-11 00:37:12 -04:00
# include "util.h"
2013-06-27 23:45:38 -04:00
2013-07-28 19:45:08 -04:00
template < class T >
2013-05-11 16:13:46 -04:00
class NodeTree {
public :
NodeTree ( ) ;
2013-07-28 19:45:08 -04:00
NodeTree ( std : : string name , T inData ) ;
2013-05-11 16:13:46 -04:00
~ NodeTree ( ) ;
2013-08-09 04:39:43 -04:00
bool const operator = = ( NodeTree & other ) ;
bool const operator < ( const NodeTree & other ) const ;
2013-07-28 23:48:10 -04:00
void setParent ( NodeTree < T > * parent ) ;
void addParent ( NodeTree < T > * parent ) ;
NodeTree < T > * getParent ( ) ;
std : : vector < NodeTree < T > * > getParents ( ) ;
void addChild ( NodeTree < T > * child ) ;
2013-11-01 02:52:18 -04:00
void insertChild ( int i , NodeTree < T > * child ) ;
2013-08-06 01:49:45 -04:00
void addChildren ( std : : vector < NodeTree < T > * > * children ) ;
2013-10-02 03:15:20 -04:00
void addChildren ( std : : vector < NodeTree < T > * > children ) ;
2013-11-01 02:52:18 -04:00
void insertChildren ( int index , std : : vector < NodeTree < T > * > * children ) ;
void insertChildren ( int index , std : : vector < NodeTree < T > * > children ) ;
2013-07-28 23:48:10 -04:00
int findChild ( NodeTree < T > * child ) ;
void removeChild ( NodeTree < T > * child ) ;
2013-05-11 16:13:46 -04:00
void removeChild ( int index ) ;
2013-08-06 01:49:45 -04:00
void clearChildren ( ) ;
2013-07-28 23:48:10 -04:00
std : : vector < NodeTree < T > * > getChildren ( ) ;
2013-05-11 16:13:46 -04:00
2013-07-28 23:48:10 -04:00
NodeTree < T > * get ( int index ) ;
2013-06-27 23:45:38 -04:00
std : : string getName ( ) ;
2013-05-11 16:13:46 -04:00
void setName ( std : : string ) ;
2013-08-09 04:39:43 -04:00
T getData ( ) const ;
2013-11-01 02:52:18 -04:00
T * getDataRef ( ) ;
2013-07-28 19:45:08 -04:00
void setData ( T data ) ;
2013-06-27 23:45:38 -04:00
2013-05-11 16:13:46 -04:00
int size ( ) ;
std : : string DOTGraphString ( ) ;
private :
2013-08-13 14:01:53 -04:00
std : : string DOTGraphStringHelper ( std : : vector < NodeTree < T > * > avoidList ) ;
2013-06-23 05:54:58 -04:00
std : : string getDOTName ( ) ;
2013-05-11 16:13:46 -04:00
std : : string name ;
2013-07-28 19:45:08 -04:00
T data ;
2013-07-28 23:48:10 -04:00
std : : vector < NodeTree < T > * > parents ;
std : : vector < NodeTree < T > * > children ;
2013-06-23 05:54:58 -04:00
static int idCounter ;
int id ;
2013-05-11 16:13:46 -04:00
} ;
2013-07-28 19:45:08 -04:00
template < class T >
int NodeTree < T > : : idCounter ;
template < class T >
NodeTree < T > : : NodeTree ( ) {
name = " UnnamedNode " ;
id = idCounter + + ;
}
template < class T >
NodeTree < T > : : NodeTree ( std : : string name , T inData ) {
this - > name = name ;
this - > data = inData ;
id = idCounter + + ;
}
template < class T >
NodeTree < T > : : ~ NodeTree ( ) {
children . clear ( ) ;
2013-07-28 23:48:10 -04:00
parents . clear ( ) ; //? Will this segfault?
2013-07-28 19:45:08 -04:00
}
2013-08-09 04:39:43 -04:00
template < class T >
const bool NodeTree < T > : : operator = = ( NodeTree & other ) {
if ( ! ( data = = other . data ) )
return false ;
if ( children . size ( ) ! = other . getChildren ( ) . size ( ) )
return false ;
for ( typename std : : vector < NodeTree < T > * > : : size_type i = 0 ; i < children . size ( ) ; i + + )
if ( ! ( * ( children [ i ] ) = = * ( other . getChildren ( ) [ i ] ) ) )
return false ;
return true ;
}
2013-10-02 03:15:20 -04:00
//Used when making a map of NodeTrees
2013-08-09 04:39:43 -04:00
template < class T >
const bool NodeTree < T > : : operator < ( const NodeTree & other ) const {
return data < other . getData ( ) ;
}
2013-07-28 19:45:08 -04:00
template < class T >
void NodeTree < T > : : setParent ( NodeTree < T > * parent ) {
2013-07-28 23:48:10 -04:00
parents . clear ( ) ;
parents . push_back ( parent ) ;
}
template < class T >
void NodeTree < T > : : addParent ( NodeTree < T > * parent ) {
parents . push_back ( parent ) ;
2013-07-28 19:45:08 -04:00
}
template < class T >
NodeTree < T > * NodeTree < T > : : getParent ( ) {
2013-07-28 23:48:10 -04:00
if ( parents . size ( ) > 0 )
return parents [ 0 ] ;
return NULL ;
}
template < class T >
std : : vector < NodeTree < T > * > NodeTree < T > : : getParents ( ) {
return parents ;
2013-07-28 19:45:08 -04:00
}
2013-07-28 23:48:10 -04:00
2013-07-28 19:45:08 -04:00
template < class T >
void NodeTree < T > : : addChild ( NodeTree < T > * child ) {
2013-08-13 14:01:53 -04:00
if ( ! child )
throw " Help, NULL child " ;
2013-07-28 19:45:08 -04:00
if ( findChild ( child ) = = - 1 )
children . push_back ( child ) ;
}
2013-11-01 02:52:18 -04:00
template < class T >
void NodeTree < T > : : insertChild ( int i , NodeTree < T > * child ) {
if ( ! child )
throw " Help, NULL child " ;
if ( findChild ( child ) = = - 1 )
children . insert ( children . begin ( ) + i , child ) ;
}
2013-08-06 01:49:45 -04:00
template < class T >
void NodeTree < T > : : addChildren ( std : : vector < NodeTree < T > * > * children ) {
2013-08-08 03:06:28 -04:00
for ( typename std : : vector < NodeTree < T > * > : : size_type i = 0 ; i < children - > size ( ) ; i + + )
2013-08-06 01:49:45 -04:00
addChild ( ( * children ) [ i ] ) ;
}
2013-10-02 03:15:20 -04:00
template < class T >
void NodeTree < T > : : addChildren ( std : : vector < NodeTree < T > * > children ) {
for ( typename std : : vector < NodeTree < T > * > : : size_type i = 0 ; i < children . size ( ) ; i + + )
addChild ( children [ i ] ) ;
}
2013-11-01 02:52:18 -04:00
template < class T >
void NodeTree < T > : : insertChildren ( int index , std : : vector < NodeTree < T > * > * children ) {
for ( typename std : : vector < NodeTree < T > * > : : size_type i = 0 ; i < children - > size ( ) ; i + + )
insertChild ( index + i , ( * children ) [ i ] ) ;
}
template < class T >
void NodeTree < T > : : insertChildren ( int index , std : : vector < NodeTree < T > * > children ) {
for ( typename std : : vector < NodeTree < T > * > : : size_type i = 0 ; i < children . size ( ) ; i + + )
insertChild ( index + i , children [ i ] ) ;
}
2013-07-28 19:45:08 -04:00
template < class T >
int NodeTree < T > : : findChild ( NodeTree < T > * child ) {
for ( int i = 0 ; i < children . size ( ) ; i + + ) {
if ( children [ i ] = = child ) {
return i ;
}
}
return - 1 ;
}
template < class T >
void NodeTree < T > : : removeChild ( int index ) {
children [ index ] = NULL ;
children . erase ( children . begin ( ) + index ) ;
}
template < class T >
void NodeTree < T > : : removeChild ( NodeTree < T > * child ) {
int index = findChild ( child ) ;
2013-07-28 23:48:10 -04:00
if ( index ! = - 1 ) {
2013-07-28 19:45:08 -04:00
removeChild ( index ) ;
}
}
2013-08-06 01:49:45 -04:00
template < class T >
void NodeTree < T > : : clearChildren ( ) {
2013-08-08 03:06:28 -04:00
for ( typename std : : vector < T > : : size_type i = 0 ; i < children . size ( ) ; i + + )
2013-08-06 01:49:45 -04:00
children [ i ] = NULL ;
children . clear ( ) ;
}
2013-07-28 23:48:10 -04:00
template < class T >
std : : vector < NodeTree < T > * > NodeTree < T > : : getChildren ( ) {
2013-07-31 23:51:05 -04:00
return children ;
2013-07-28 23:48:10 -04:00
}
2013-07-28 19:45:08 -04:00
template < class T >
int NodeTree < T > : : size ( ) {
int count = 0 ;
for ( int i = 0 ; i < children . size ( ) ; i + + ) {
count + = children [ i ] - > size ( ) ;
}
return 1 + count ;
}
template < class T >
NodeTree < T > * NodeTree < T > : : get ( int index ) {
return children [ index ] ;
}
template < class T >
std : : string NodeTree < T > : : getName ( ) {
return name ;
}
template < class T >
void NodeTree < T > : : setName ( std : : string name ) {
this - > name = name ;
}
template < class T >
2013-08-09 04:39:43 -04:00
T NodeTree < T > : : getData ( ) const {
2013-07-28 19:45:08 -04:00
return data ;
}
2013-11-01 02:52:18 -04:00
template < class T >
T * NodeTree < T > : : getDataRef ( ) {
return & data ;
}
2013-07-28 19:45:08 -04:00
template < class T >
void NodeTree < T > : : setData ( T data ) {
this - > data = data ;
}
template < class T >
std : : string NodeTree < T > : : DOTGraphString ( ) {
2013-08-13 14:01:53 -04:00
return ( " digraph Kraken { \n " + DOTGraphStringHelper ( std : : vector < NodeTree < T > * > ( ) ) + " } " ) ;
2013-07-28 19:45:08 -04:00
}
template < class T >
2013-08-13 14:01:53 -04:00
std : : string NodeTree < T > : : DOTGraphStringHelper ( std : : vector < NodeTree < T > * > avoidList ) {
for ( typename std : : vector < NodeTree < T > * > : : size_type i = 0 ; i < avoidList . size ( ) ; i + + )
if ( this = = avoidList [ i ] )
return " " ;
avoidList . push_back ( this ) ;
2013-07-28 19:45:08 -04:00
std : : string ourDOTRelation = " " ;
for ( int i = 0 ; i < children . size ( ) ; i + + ) {
2013-08-09 04:39:43 -04:00
if ( children [ i ] ! = NULL )
2013-08-13 14:01:53 -04:00
ourDOTRelation + = getDOTName ( ) + " -> " + children [ i ] - > getDOTName ( ) + " ; \n " + children [ i ] - > DOTGraphStringHelper ( avoidList ) ;
2013-08-09 04:39:43 -04:00
else
2013-08-10 18:24:37 -04:00
ourDOTRelation + = getDOTName ( ) + " -> BAD_NULL_ " + getDOTName ( ) + " \n " ;
2013-07-28 19:45:08 -04:00
}
return ( ourDOTRelation ) ;
}
template < class T >
std : : string NodeTree < T > : : getDOTName ( ) {
2013-08-11 00:37:12 -04:00
std : : string DOTName = " " ;
2013-10-02 03:15:20 -04:00
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) + "\"";
2013-08-11 01:15:26 -04:00
return ( replaceExEscape ( DOTName , " \n " , " \\ n " ) ) ;
2013-07-28 19:45:08 -04:00
}
2013-05-20 19:34:15 -04:00
# endif