// file: $isip/class/dstr/TreeNode/TreeNode.h // version: $Id: TreeNode.h 8646 2002-08-23 01:06:43Z alphonso $ // // make sure definitions are made only once // #ifndef ISIP_TREE_NODE #define ISIP_TREE_NODE // isip include files // #ifndef ISIP_LONG #include #endif #ifndef ISIP_NODE #include #endif #ifndef ISIP_CONSOLE #include #endif // forward class definitions // template class TreeNodeDiagnose; // TreeNode: this class implements a TreeNode data structure that forms the // basis of the Tree class // template class TreeNode : public Node { //--------------------------------------------------------------------------- // // public constants // //--------------------------------------------------------------------------- public: // define the class name // static const String CLASS_NAME; //---------------------------------------- // // i/o related constants // //---------------------------------------- static const String DEF_PARAM; //---------------------------------------- // // default values and arguments // //---------------------------------------- // default values // static const int32 DEF_DEGREE = 0; // default arguments to methods // //---------------------------------------- // // error codes // //---------------------------------------- //--------------------------------------------------------------------------- // // protected data // //--------------------------------------------------------------------------- protected: // define a pointer to the parent node // TreeNode* parent_d; // define a pointer to the left child node // TreeNode* left_d; // define a pointer to the right child node // TreeNode* right_d; // define the out degree of the node // Long degree_d; // debugging parameters // static Integral::DEBUG debug_level_d; // define the memory manager // static MemoryManager mgr_d; //--------------------------------------------------------------------------- // // required public methods // //--------------------------------------------------------------------------- public: // static methods: // the diagnose method is moved outside the class header file and // defined in the TreeNodeDiagnose.h in order to avoid issues // with preprocessing of the diagnose code. // static const String& name(); // method: setDebug // static bool8 setDebug(Integral::DEBUG debug_level) { debug_level_d = debug_level; return true; } // other debug methods // bool8 debug(const unichar* msg) const; // destructor/constructor(s) // ~TreeNode(); TreeNode(TObject* item = (TObject*)NULL); TreeNode(const TreeNode& copy_tnode); // assign method // bool8 assign(const TreeNode& copy_stack); // method: operator= // TreeNode& operator=(const TreeNode& arg) { assign(arg); return *this; } // equality method // bool8 eq(const TreeNode& arg) const; // method: read // bool8 read(Sof& sof, int32 tag) { return read(sof, tag, name()); } // method: write // bool8 write(Sof& sof, int32 tag) const { return write(sof, tag, name()); } // method: sofSize // int32 sofSize() const { return 0; } // method: read // bool8 read(Sof& sof, int32 tag, const String& name) { return Error::handle(name(), L"read", Error::ARG, __FILE__, __LINE__); } // method: write // bool8 write(Sof& sof, int32 tag, const String& name) const { return Error::handle(name(), L"write", Error::ARG, __FILE__, __LINE__); } // method: readData // bool8 readData(Sof& sof, const String& pname = DEF_PARAM, int32 size = SofParser::FULL_OBJECT, bool8 param = true, bool8 nested = true) { return Error::handle(name(), L"readData", Error::ARG, __FILE__, __LINE__); } // method: writeData // bool8 writeData(Sof& sof, const String& pname = DEF_PARAM) const { return Error::handle(name(), L"writeData", Error::ARG, __FILE__, __LINE__); } // method: new // static void* operator new(size_t size) { return mgr_d.get(); } // method: new[] // static void* operator new[](size_t size) { return mgr_d.getBlock(size); } // method: delete // static void operator delete(void* ptr) { mgr_d.release(ptr); } // method: delete[] // static void operator delete[](void* ptr) { mgr_d.releaseBlock(ptr); } // method: setGrowSize // static bool8 setGrowSize(int32 grow_size) { return mgr_d.setGrow(grow_size); } // clear method // bool8 clear(Integral::CMODE cmode = Integral::DEF_CMODE); //--------------------------------------------------------------------------- // // class-specific public methods: // tree node manipulation methods // //--------------------------------------------------------------------------- // method: degree // int32 degree() const { return (int32)degree_d; } // method: increment // bool8 increment() { degree_d = (int32)degree_d + 1; return true; } // method: decrement // bool8 decrement() { degree_d = (int32)degree_d - 1; return true; } // method: getParent // TreeNode* getParent() const { return parent_d; } // method: setParent // bool8 setParent(const TreeNode* arg) { parent_d = const_cast* >(arg); return true; } // method: getLeftChild // TreeNode* getLeftChild() const { return left_d; } // method to set the left child of the node // bool8 setLeftChild(const TreeNode* arg); // method: getRightSibling // TreeNode* getRightSibling() const { return right_d; } // method to set the right sibling of the node // bool8 setRightSibling(const TreeNode* arg); // node adjacency methods // bool8 isAdjacent(const TObject* obj) const; bool8 isAdjacent(const TreeNode* node) const; //--------------------------------------------------------------------------- // // private methods // //--------------------------------------------------------------------------- private: // declare friend classes // template friend class TreeNodeDiagnose; }; //----------------------------------------------------------------------------- // // we define non-integral constants at the end of class definition for // templates (for non-templates these are defined in the default constructor) // //----------------------------------------------------------------------------- // constants: required constants such as the class name // template const String TreeNode::CLASS_NAME(L"TreeNode"); template const String TreeNode::DEF_PARAM(L"values"); // static instantiations: debug level // template Integral::DEBUG TreeNode::debug_level_d = Integral::NONE; // static instantiations: the memory manager // template MemoryManager TreeNode::mgr_d(sizeof(TreeNode), CLASS_NAME); // below are all the methods for the TreeNode template class // // --------------------------------------------------------------------- // // required static methods // //---------------------------------------------------------------------- // method: name // // arguments: none // // return: a static String& containing the class name // // this method returns the class name // template const String& TreeNode::name() { // create the static name string for this class and return it // static String cname(CLASS_NAME); cname.clear(); cname.concat(CLASS_NAME); cname.concat(L"<"); cname.concat(TObject::name()); cname.concat(L">"); // return the name // return cname; } // --------------------------------------------------------------------- // // required debug methods // //---------------------------------------------------------------------- // method: debug // // arguments: // unichar* msg: (input) information msg // // return: a bool8 value indicating status // // this method dumps the contents of an object to the console // template bool8 TreeNode::debug(const unichar* msg_a) const { // declare temporary strings to hold class data // String output; String value; // dump the item // value.assign((int32)item_d); output.debugStr(name(), msg_a, L"item_d", value); Console::put(output); // dump the parent node // value.assign((int32)parent_d); output.debugStr(name(), msg_a, L"parent_d", value); Console::put(output); // dump the left child // value.assign((int32)left_d); output.debugStr(name(), msg_a, L"left_d", value); Console::put(output); // dump the right sibling // value.assign((int32)right_d); output.debugStr(name(), msg_a, L"right_d", value); Console::put(output); // exit gracefully // return true; } //------------------------------------------------------------------------ // // required destructor/constructor(s) // //----------------------------------------------------------------------- // method: destructor // // arguments: none // // return: none // template TreeNode::~TreeNode() { // free memory // clear(); } // method: default constructor // // arguments: none // // return: none // template TreeNode::TreeNode(TObject* item_a) { // initialize the item // Node::setItem(item_a); // initialize the remaining member data // parent_d = (TreeNode*)NULL; left_d = (TreeNode*)NULL; right_d = (TreeNode*)NULL; degree_d = DEF_DEGREE; } // method: copy constructor // // arguments: // const TreeNode& copy_tnode: (input) the TreeNode to copy // // return: none // template TreeNode::TreeNode(const TreeNode& copy_tnode_a) { // call the assign method to copy the TreeNode // assign(copy_tnode_a); } //------------------------------------------------------------------------ // // required assign methods // //------------------------------------------------------------------------- // method: assign // // arguments: // const TreeNode& copy_tnode: (input) the TreeNode to copy // // return: a bool8 value indicating status // // this method copies the contents of the input to this TreeNode // template bool8 TreeNode::assign(const TreeNode& copy_tnode_a) { // set the item // Node::assign(copy_tnode_a); // exit gracefully // return true; } //------------------------------------------------------------------------ // // required equality methods // //------------------------------------------------------------------------ // method: eq // // arguments: // const TreeNode& compare_tnode: (input) the TreeNode to compare // // return: a bool8 value indicating status // // this method compares two TreeNodes for equivalence. two // TreeNodes are equivalent if all corresponding items are equivalent // template bool8 TreeNode::eq(const TreeNode& compare_tnode_a) const { // compare the item // if ((item_d == (TObject*)NULL) ^ (compare_tnode_a.item_d == (TObject*)NULL)) { return false; } if ((item_d != (TObject*)NULL) && (compare_tnode_a.item_d != (TObject*)NULL)) { if (!Node::eq(compare_tnode_a)) { return false; } } // if we have reached this far then they must be the same // return true; } //------------------------------------------------------------------------- // // required memory management methods // //------------------------------------------------------------------------- // method: clear // // arguments: // Integral::CMODE cmode_a: (input) clear mode // // return: a bool8 value indicating status // // this method clears the contents of the list by the setting of cmode_a // template bool8 TreeNode::clear(Integral::CMODE cmode_a) { // clear the item // if (!Node::clear(cmode_a)) { return false; } // clear the remaining member data // if (cmode_a != Integral::RETAIN) { parent_d = (TreeNode*)NULL; left_d = (TreeNode*)NULL; right_d = (TreeNode*)NULL; degree_d = DEF_DEGREE; } // exit gracefully // return true; } //------------------------------------------------------------------------ // // class-specific public methods: // tree node manipulation methods // //------------------------------------------------------------------------ // method: setLeftChild // // arguments: // const TreeNode* arg: (input) left child // // return: a bool8 value indicating status // // this method sets the left child of the current node // template bool8 TreeNode::setLeftChild(const TreeNode* arg_a) { // set the left child // left_d = const_cast* >(arg_a); // exit gracefully // return true; } // method: setRightSibling // // arguments: // const TreeNode* arg: (input) left child // // return: a bool8 value indicating status // // this method sets the right sibling of the current node // template bool8 TreeNode::setRightSibling(const TreeNode* arg_a) { // set the right sibling // right_d = const_cast* >(arg_a); // exit gracefully // return true; } // method: isAdjacent // // arguments: // const TObject* : (input) object to look for // // return: a bool8 value indicating status // // this method determines if the object is adjacent to the current node // template bool8 TreeNode::isAdjacent(const TObject* obj_a) const { // verify the input // if (obj_a == (TObject*)NULL) { return Error::handle(name(), L"isAdjacent", Error::ARG, __FILE__, __LINE__); } // check the left child // if (left_d != (TreeNode*)NULL) { if (left_d->getItem()->eq(*obj_a)) { return true; } // check the right siblings // TreeNode* rnode = left_d->getRightSibling(); while (rnode != (TreeNode*)NULL) { if (rnode->getItem()->eq(*obj_a)) { return true; } rnode = rnode->getRightSibling(); } } // if we reach this far then the object must not be adjacent // return false; } // method: isAdjacent // // arguments: // const TObject* : (input) object to look for // // return: a bool8 value indicating status // // this method determines if the object is adjacent to the current node // template bool8 TreeNode::isAdjacent(const TreeNode* node_a) const { // verify the input // if (node_a == (TreeNode*)NULL) { return Error::handle(name(), L"isAdjacent", Error::ARG, __FILE__, __LINE__); } // check the left child // if (left_d != (TreeNode*)NULL) { if (left_d->eq(*node_a)) { return true; } // check the right siblings // TreeNode* rnode = left_d->getRightSibling(); while (rnode != (TreeNode*)NULL) { if (rnode->eq(*node_a)) { return true; } rnode = rnode->getRightSibling(); } } // if we reach this far then the object must not be adjacent // return false; } // end of include file // #endif